diff --git a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs
index d45fa2a427..4a7b505363 100644
--- a/src/ImageSharp/Formats/Webp/AlphaDecoder.cs
+++ b/src/ImageSharp/Formats/Webp/AlphaDecoder.cs
@@ -1,8 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers;
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -110,6 +110,7 @@ internal class AlphaDecoder : IDisposable
///
/// Gets a value indicating whether the alpha channel uses compression.
///
+ [MemberNotNullWhen(true, nameof(LosslessDecoder))]
private bool Compressed { get; }
///
@@ -120,7 +121,7 @@ internal class AlphaDecoder : IDisposable
///
/// Gets the Vp8L decoder which is used to de compress the alpha channel, if needed.
///
- private WebpLosslessDecoder LosslessDecoder { get; }
+ private WebpLosslessDecoder? LosslessDecoder { get; }
///
/// Gets a value indicating whether the decoding needs 1 byte per pixel for decoding.
diff --git a/src/ImageSharp/Formats/Webp/AlphaEncoder.cs b/src/ImageSharp/Formats/Webp/AlphaEncoder.cs
index 292c31f6a5..dd21365bc3 100644
--- a/src/ImageSharp/Formats/Webp/AlphaEncoder.cs
+++ b/src/ImageSharp/Formats/Webp/AlphaEncoder.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers;
using SixLabors.ImageSharp.Advanced;
@@ -15,7 +14,7 @@ namespace SixLabors.ImageSharp.Formats.Webp;
///
internal class AlphaEncoder : IDisposable
{
- private IMemoryOwner alphaData;
+ private IMemoryOwner? alphaData;
///
/// Encodes the alpha channel data.
diff --git a/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs b/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs
index 2586690fd3..fa121be4f5 100644
--- a/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs
+++ b/src/ImageSharp/Formats/Webp/BitReader/BitReaderBase.cs
@@ -1,8 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers;
+using System.Diagnostics.CodeAnalysis;
using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Webp.BitReader;
@@ -17,7 +17,7 @@ internal abstract class BitReaderBase : IDisposable
///
/// Gets or sets the raw encoded image data.
///
- public IMemoryOwner Data { get; set; }
+ public IMemoryOwner? Data { get; set; }
///
/// Copies the raw encoded image data from the stream into a byte array.
@@ -25,6 +25,7 @@ internal abstract class BitReaderBase : IDisposable
/// The input stream.
/// Number of bytes to read as indicated from the chunk size.
/// Used for allocating memory during reading data from the stream.
+ [MemberNotNull(nameof(Data))]
protected void ReadImageDataFromStream(Stream input, int bytesToRead, MemoryAllocator memoryAllocator)
{
this.Data = memoryAllocator.Allocate(bytesToRead);
diff --git a/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs b/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs
index 07bfcccd91..1fa4deda97 100644
--- a/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs
+++ b/src/ImageSharp/Formats/Webp/BitReader/Vp8BitReader.cs
@@ -186,7 +186,7 @@ internal class Vp8BitReader : BitReaderBase
{
if (this.pos < this.bufferMax)
{
- ulong inBits = BinaryPrimitives.ReadUInt64LittleEndian(this.Data.Memory.Span.Slice((int)this.pos, 8));
+ ulong inBits = BinaryPrimitives.ReadUInt64LittleEndian(this.Data!.Memory.Span.Slice((int)this.pos, 8));
this.pos += BitsCount >> 3;
ulong bits = ByteSwap64(inBits);
bits >>= 64 - BitsCount;
@@ -205,7 +205,7 @@ internal class Vp8BitReader : BitReaderBase
if (this.pos < this.bufferEnd)
{
this.bits += 8;
- this.value = this.Data.Memory.Span[(int)this.pos++] | (this.value << 8);
+ this.value = this.Data!.Memory.Span[(int)this.pos++] | (this.value << 8);
}
else if (!this.eof)
{
diff --git a/src/ImageSharp/Formats/Webp/BitReader/Vp8LBitReader.cs b/src/ImageSharp/Formats/Webp/BitReader/Vp8LBitReader.cs
index 057abf134a..df95f01f4a 100644
--- a/src/ImageSharp/Formats/Webp/BitReader/Vp8LBitReader.cs
+++ b/src/ImageSharp/Formats/Webp/BitReader/Vp8LBitReader.cs
@@ -193,7 +193,7 @@ internal class Vp8LBitReader : BitReaderBase
[MethodImpl(InliningOptions.ShortMethod)]
private void ShiftBytes()
{
- System.Span dataSpan = this.Data.Memory.Span;
+ System.Span dataSpan = this.Data!.Memory.Span;
while (this.bitPos >= 8 && this.pos < this.len)
{
this.value >>= 8;
diff --git a/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs b/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs
index 2df02727e0..02b1d0ab6a 100644
--- a/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs
+++ b/src/ImageSharp/Formats/Webp/BitWriter/BitWriterBase.cs
@@ -123,7 +123,7 @@ internal abstract class BitWriterBase
/// The stream to write to.
/// The metadata profile's bytes.
/// The chuck type to write.
- protected void WriteMetadataProfile(Stream stream, byte[] metadataBytes, WebpChunkType chunkType)
+ protected void WriteMetadataProfile(Stream stream, byte[]? metadataBytes, WebpChunkType chunkType)
{
DebugGuard.NotNull(metadataBytes, nameof(metadataBytes));
@@ -207,7 +207,7 @@ internal abstract class BitWriterBase
/// The width of the image.
/// The height of the image.
/// Flag indicating, if a alpha channel is present.
- protected void WriteVp8XHeader(Stream stream, ExifProfile exifProfile, XmpProfile xmpProfile, byte[] iccProfileBytes, uint width, uint height, bool hasAlpha)
+ protected void WriteVp8XHeader(Stream stream, ExifProfile? exifProfile, XmpProfile? xmpProfile, byte[]? iccProfileBytes, uint width, uint height, bool hasAlpha)
{
if (width > MaxDimension || height > MaxDimension)
{
diff --git a/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs b/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
index 6fa02c1161..b83b44fa14 100644
--- a/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
+++ b/src/ImageSharp/Formats/Webp/BitWriter/Vp8BitWriter.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers.Binary;
using SixLabors.ImageSharp.Formats.Webp.Lossy;
@@ -58,7 +57,8 @@ internal class Vp8BitWriter : BitWriterBase
/// Initializes a new instance of the class.
///
/// The expected size in bytes.
- public Vp8BitWriter(int expectedSize)
+ /// The Vp8Encoder.
+ public Vp8BitWriter(int expectedSize, Vp8Encoder enc)
: base(expectedSize)
{
this.range = 255 - 1;
@@ -67,15 +67,9 @@ internal class Vp8BitWriter : BitWriterBase
this.nbBits = -8;
this.pos = 0;
this.maxPos = 0;
- }
- ///
- /// Initializes a new instance of the class.
- ///
- /// The expected size in bytes.
- /// The Vp8Encoder.
- public Vp8BitWriter(int expectedSize, Vp8Encoder enc)
- : this(expectedSize) => this.enc = enc;
+ this.enc = enc;
+ }
///
public override int NumBytes() => (int)this.pos;
@@ -414,9 +408,9 @@ internal class Vp8BitWriter : BitWriterBase
/// Indicates, if the alpha data is compressed.
public void WriteEncodedImageToStream(
Stream stream,
- ExifProfile exifProfile,
- XmpProfile xmpProfile,
- IccProfile iccProfile,
+ ExifProfile? exifProfile,
+ XmpProfile? xmpProfile,
+ IccProfile? iccProfile,
uint width,
uint height,
bool hasAlpha,
@@ -424,22 +418,22 @@ internal class Vp8BitWriter : BitWriterBase
bool alphaDataIsCompressed)
{
bool isVp8X = false;
- byte[] exifBytes = null;
- byte[] xmpBytes = null;
- byte[] iccProfileBytes = null;
+ byte[]? exifBytes = null;
+ byte[]? xmpBytes = null;
+ byte[]? iccProfileBytes = null;
uint riffSize = 0;
if (exifProfile != null)
{
isVp8X = true;
exifBytes = exifProfile.ToByteArray();
- riffSize += MetadataChunkSize(exifBytes);
+ riffSize += MetadataChunkSize(exifBytes!);
}
if (xmpProfile != null)
{
isVp8X = true;
xmpBytes = xmpProfile.Data;
- riffSize += MetadataChunkSize(xmpBytes);
+ riffSize += MetadataChunkSize(xmpBytes!);
}
if (iccProfile != null)
@@ -465,7 +459,7 @@ internal class Vp8BitWriter : BitWriterBase
int mbSize = this.enc.Mbw * this.enc.Mbh;
int expectedSize = mbSize * 7 / 8;
- var bitWriterPartZero = new Vp8BitWriter(expectedSize);
+ Vp8BitWriter bitWriterPartZero = new(expectedSize, this.enc);
// Partition #0 with header and partition sizes.
uint size0 = this.GeneratePartition0(bitWriterPartZero);
@@ -676,9 +670,9 @@ internal class Vp8BitWriter : BitWriterBase
bool isVp8X,
uint width,
uint height,
- ExifProfile exifProfile,
- XmpProfile xmpProfile,
- byte[] iccProfileBytes,
+ ExifProfile? exifProfile,
+ XmpProfile? xmpProfile,
+ byte[]? iccProfileBytes,
bool hasAlpha,
Span alphaData,
bool alphaDataIsCompressed)
diff --git a/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs b/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs
index 42c1af8040..22bc195d64 100644
--- a/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs
+++ b/src/ImageSharp/Formats/Webp/BitWriter/Vp8LBitWriter.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers.Binary;
using SixLabors.ImageSharp.Formats.Webp.Lossless;
@@ -138,25 +137,25 @@ internal class Vp8LBitWriter : BitWriterBase
/// The width of the image.
/// The height of the image.
/// Flag indicating, if a alpha channel is present.
- public void WriteEncodedImageToStream(Stream stream, ExifProfile exifProfile, XmpProfile xmpProfile, IccProfile iccProfile, uint width, uint height, bool hasAlpha)
+ public void WriteEncodedImageToStream(Stream stream, ExifProfile? exifProfile, XmpProfile? xmpProfile, IccProfile? iccProfile, uint width, uint height, bool hasAlpha)
{
bool isVp8X = false;
- byte[] exifBytes = null;
- byte[] xmpBytes = null;
- byte[] iccBytes = null;
+ byte[]? exifBytes = null;
+ byte[]? xmpBytes = null;
+ byte[]? iccBytes = null;
uint riffSize = 0;
if (exifProfile != null)
{
isVp8X = true;
exifBytes = exifProfile.ToByteArray();
- riffSize += MetadataChunkSize(exifBytes);
+ riffSize += MetadataChunkSize(exifBytes!);
}
if (xmpProfile != null)
{
isVp8X = true;
xmpBytes = xmpProfile.Data;
- riffSize += MetadataChunkSize(xmpBytes);
+ riffSize += MetadataChunkSize(xmpBytes!);
}
if (iccProfile != null)
diff --git a/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs b/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs
index b3589b52c7..df19c26e0b 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers;
using SixLabors.ImageSharp.Memory;
@@ -50,7 +49,7 @@ internal static class BackwardReferenceEncoder
int lz77TypeBest = 0;
double bitCostBest = -1;
int cacheBitsInitial = cacheBits;
- Vp8LHashChain hashChainBox = null;
+ Vp8LHashChain? hashChainBox = null;
var stats = new Vp8LStreaks();
var bitsEntropy = new Vp8LBitEntropy();
for (int lz77Type = 1; lz77TypesToTry > 0; lz77TypesToTry &= ~lz77Type, lz77Type <<= 1)
@@ -101,7 +100,7 @@ internal static class BackwardReferenceEncoder
// Improve on simple LZ77 but only for high quality (TraceBackwards is costly).
if ((lz77TypeBest == (int)Vp8LLz77Type.Lz77Standard || lz77TypeBest == (int)Vp8LLz77Type.Lz77Box) && quality >= 25)
{
- Vp8LHashChain hashChainTmp = lz77TypeBest == (int)Vp8LLz77Type.Lz77Standard ? hashChain : hashChainBox;
+ Vp8LHashChain hashChainTmp = lz77TypeBest == (int)Vp8LLz77Type.Lz77Standard ? hashChain : hashChainBox!;
BackwardReferencesTraceBackwards(width, height, memoryAllocator, bgra, cacheBits, hashChainTmp, best, worst);
var histo = new Vp8LHistogram(worst, cacheBits);
double bitCostTrace = histo.EstimateBits(stats, bitsEntropy);
@@ -140,8 +139,7 @@ internal static class BackwardReferenceEncoder
for (int i = 0; i <= WebpConstants.MaxColorCacheBits; i++)
{
histos[i] = new Vp8LHistogram(paletteCodeBits: i);
- colorCache[i] = new ColorCache();
- colorCache[i].Init(i);
+ colorCache[i] = new ColorCache(i);
}
// Find the cacheBits giving the lowest entropy.
@@ -274,11 +272,11 @@ internal static class BackwardReferenceEncoder
double offsetCost = -1;
int firstOffsetIsConstant = -1; // initialized with 'impossible' value.
int reach = 0;
- var colorCache = new ColorCache();
+ ColorCache? colorCache = null;
if (useColorCache)
{
- colorCache.Init(cacheBits);
+ colorCache = new ColorCache(cacheBits);
}
costModel.Build(xSize, cacheBits, refs);
@@ -375,12 +373,12 @@ internal static class BackwardReferenceEncoder
private static void BackwardReferencesHashChainFollowChosenPath(ReadOnlySpan bgra, int cacheBits, Span chosenPath, int chosenPathSize, Vp8LHashChain hashChain, Vp8LBackwardRefs backwardRefs)
{
bool useColorCache = cacheBits > 0;
- var colorCache = new ColorCache();
+ ColorCache? colorCache = null;
int i = 0;
if (useColorCache)
{
- colorCache.Init(cacheBits);
+ colorCache = new ColorCache(cacheBits);
}
backwardRefs.Refs.Clear();
@@ -396,7 +394,7 @@ internal static class BackwardReferenceEncoder
{
for (int k = 0; k < len; k++)
{
- colorCache.Insert(bgra[i + k]);
+ colorCache!.Insert(bgra[i + k]);
}
}
@@ -405,7 +403,7 @@ internal static class BackwardReferenceEncoder
else
{
PixOrCopy v;
- int idx = useColorCache ? colorCache.Contains(bgra[i]) : -1;
+ int idx = useColorCache ? colorCache!.Contains(bgra[i]) : -1;
if (idx >= 0)
{
// useColorCache is true and color cache contains bgra[i]
@@ -416,7 +414,7 @@ internal static class BackwardReferenceEncoder
{
if (useColorCache)
{
- colorCache.Insert(bgra[i]);
+ colorCache!.Insert(bgra[i]);
}
v = PixOrCopy.CreateLiteral(bgra[i]);
@@ -430,7 +428,7 @@ internal static class BackwardReferenceEncoder
private static void AddSingleLiteralWithCostModel(
ReadOnlySpan bgra,
- ColorCache colorCache,
+ ColorCache? colorCache,
CostModel costModel,
int idx,
bool useColorCache,
@@ -440,7 +438,7 @@ internal static class BackwardReferenceEncoder
{
double costVal = prevCost;
uint color = bgra[idx];
- int ix = useColorCache ? colorCache.Contains(color) : -1;
+ int ix = useColorCache ? colorCache!.Contains(color) : -1;
if (ix >= 0)
{
double mul0 = 0.68;
@@ -451,7 +449,7 @@ internal static class BackwardReferenceEncoder
double mul1 = 0.82;
if (useColorCache)
{
- colorCache.Insert(color);
+ colorCache!.Insert(color);
}
costVal += costModel.GetLiteralCost(color) * mul1;
@@ -469,10 +467,10 @@ internal static class BackwardReferenceEncoder
int iLastCheck = -1;
bool useColorCache = cacheBits > 0;
int pixCount = xSize * ySize;
- var colorCache = new ColorCache();
+ ColorCache? colorCache = null;
if (useColorCache)
{
- colorCache.Init(cacheBits);
+ colorCache = new ColorCache(cacheBits);
}
refs.Refs.Clear();
@@ -529,7 +527,7 @@ internal static class BackwardReferenceEncoder
{
for (j = i; j < i + len; j++)
{
- colorCache.Insert(bgra[j]);
+ colorCache!.Insert(bgra[j]);
}
}
}
@@ -725,11 +723,11 @@ internal static class BackwardReferenceEncoder
{
int pixelCount = xSize * ySize;
bool useColorCache = cacheBits > 0;
- var colorCache = new ColorCache();
+ ColorCache? colorCache = null;
if (useColorCache)
{
- colorCache.Init(cacheBits);
+ colorCache = new ColorCache(cacheBits);
}
refs.Refs.Clear();
@@ -757,7 +755,7 @@ internal static class BackwardReferenceEncoder
{
for (int k = 0; k < prevRowLen; ++k)
{
- colorCache.Insert(bgra[i + k]);
+ colorCache!.Insert(bgra[i + k]);
}
}
@@ -777,8 +775,7 @@ internal static class BackwardReferenceEncoder
private static void BackwardRefsWithLocalCache(ReadOnlySpan bgra, int cacheBits, Vp8LBackwardRefs refs)
{
int pixelIndex = 0;
- var colorCache = new ColorCache();
- colorCache.Init(cacheBits);
+ ColorCache colorCache = new(cacheBits);
for (int idx = 0; idx < refs.Refs.Count; idx++)
{
PixOrCopy v = refs.Refs[idx];
@@ -825,12 +822,12 @@ internal static class BackwardReferenceEncoder
}
}
- private static void AddSingleLiteral(uint pixel, bool useColorCache, ColorCache colorCache, Vp8LBackwardRefs refs)
+ private static void AddSingleLiteral(uint pixel, bool useColorCache, ColorCache? colorCache, Vp8LBackwardRefs refs)
{
PixOrCopy v;
if (useColorCache)
{
- int key = colorCache.GetIndex(pixel);
+ int key = colorCache!.GetIndex(pixel);
if (colorCache.Lookup(key) == pixel)
{
v = PixOrCopy.CreateCacheIdx(key);
diff --git a/src/ImageSharp/Formats/Webp/Lossless/ColorCache.cs b/src/ImageSharp/Formats/Webp/Lossless/ColorCache.cs
index 08ff60b69f..7e1c4e2fe1 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/ColorCache.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/ColorCache.cs
@@ -1,7 +1,7 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
+using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.Webp.Lossless;
@@ -13,6 +13,18 @@ internal class ColorCache
{
private const uint HashMul = 0x1e35a7bdu;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The hashBits determine the size of cache. It will be 1 left shifted by hashBits.
+ public ColorCache(int hashBits)
+ {
+ int hashSize = 1 << hashBits;
+ this.Colors = new uint[hashSize];
+ this.HashBits = hashBits;
+ this.HashShift = 32 - hashBits;
+ }
+
///
/// Gets the color entries.
///
@@ -28,18 +40,6 @@ internal class ColorCache
///
public int HashBits { get; private set; }
- ///
- /// Initializes a new color cache.
- ///
- /// The hashBits determine the size of cache. It will be 1 left shifted by hashBits.
- public void Init(int hashBits)
- {
- int hashSize = 1 << hashBits;
- this.Colors = new uint[hashSize];
- this.HashBits = hashBits;
- this.HashShift = 32 - hashBits;
- }
-
///
/// Inserts a new color into the cache.
///
diff --git a/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs b/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs
index abfb67bc7e..84ddd4b785 100644
--- a/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs
+++ b/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs
@@ -158,10 +158,9 @@ internal sealed class WebpLosslessDecoder
// Finish setting up the color-cache.
if (isColorCachePresent)
{
- decoder.Metadata.ColorCache = new ColorCache();
+ decoder.Metadata.ColorCache = new ColorCache(colorCacheBits);
colorCacheSize = 1 << colorCacheBits;
decoder.Metadata.ColorCacheSize = colorCacheSize;
- decoder.Metadata.ColorCache.Init(colorCacheBits);
}
else
{
diff --git a/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs b/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs
index 4c1c60591d..abaa85ef18 100644
--- a/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs
+++ b/src/ImageSharp/Formats/Webp/WebpAnimationDecoder.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers;
using System.Runtime.CompilerServices;
@@ -46,17 +45,17 @@ internal class WebpAnimationDecoder : IDisposable
///
/// The abstract metadata.
///
- private ImageMetadata metadata;
+ private ImageMetadata? metadata;
///
/// The gif specific metadata.
///
- private WebpMetadata webpMetadata;
+ private WebpMetadata? webpMetadata;
///
/// The alpha data, if an ALPH chunk is present.
///
- private IMemoryOwner alphaData;
+ private IMemoryOwner? alphaData;
///
/// Initializes a new instance of the class.
@@ -83,8 +82,8 @@ internal class WebpAnimationDecoder : IDisposable
public Image Decode(BufferedReadStream stream, WebpFeatures features, uint width, uint height, uint completeDataSize)
where TPixel : unmanaged, IPixel
{
- Image image = null;
- ImageFrame previousFrame = null;
+ Image? image = null;
+ ImageFrame? previousFrame = null;
this.metadata = new ImageMetadata();
this.webpMetadata = this.metadata.GetWebpMetadata();
@@ -99,12 +98,12 @@ internal class WebpAnimationDecoder : IDisposable
switch (chunkType)
{
case WebpChunkType.Animation:
- uint dataSize = this.ReadFrame(stream, ref image, ref previousFrame, width, height, features.AnimationBackgroundColor.Value);
+ uint dataSize = this.ReadFrame(stream, ref image, ref previousFrame, width, height, features.AnimationBackgroundColor!.Value);
remainingBytes -= (int)dataSize;
break;
case WebpChunkType.Xmp:
case WebpChunkType.Exif:
- WebpChunkParsingUtils.ParseOptionalChunks(stream, chunkType, image.Metadata, false, this.buffer);
+ WebpChunkParsingUtils.ParseOptionalChunks(stream, chunkType, image!.Metadata, false, this.buffer);
break;
default:
WebpThrowHelper.ThrowImageFormatException("Read unexpected webp chunk data");
@@ -117,7 +116,7 @@ internal class WebpAnimationDecoder : IDisposable
}
}
- return image;
+ return image!;
}
///
@@ -130,7 +129,7 @@ internal class WebpAnimationDecoder : IDisposable
/// The width of the image.
/// The height of the image.
/// The default background color of the canvas in.
- private uint ReadFrame(BufferedReadStream stream, ref Image image, ref ImageFrame previousFrame, uint width, uint height, Color backgroundColor)
+ private uint ReadFrame(BufferedReadStream stream, ref Image? image, ref ImageFrame? previousFrame, uint width, uint height, Color backgroundColor)
where TPixel : unmanaged, IPixel
{
AnimationFrameData frameData = this.ReadFrameHeader(stream);
@@ -146,7 +145,7 @@ internal class WebpAnimationDecoder : IDisposable
chunkType = WebpChunkParsingUtils.ReadChunkType(stream, this.buffer);
}
- WebpImageInfo webpInfo = null;
+ WebpImageInfo? webpInfo = null;
WebpFeatures features = new();
switch (chunkType)
{
@@ -163,7 +162,7 @@ internal class WebpAnimationDecoder : IDisposable
break;
}
- ImageFrame currentFrame = null;
+ ImageFrame? currentFrame = null;
ImageFrame imageFrame;
if (previousFrame is null)
{
@@ -175,7 +174,7 @@ internal class WebpAnimationDecoder : IDisposable
}
else
{
- currentFrame = image.Frames.AddFrame(previousFrame); // This clones the frame and adds it the collection.
+ currentFrame = image!.Frames.AddFrame(previousFrame); // This clones the frame and adds it the collection.
SetFrameMetadata(currentFrame.Metadata, frameData.Duration);
diff --git a/src/ImageSharp/Formats/Webp/WebpChunkParsingUtils.cs b/src/ImageSharp/Formats/Webp/WebpChunkParsingUtils.cs
index bfe415a6e4..e4acdf311c 100644
--- a/src/ImageSharp/Formats/Webp/WebpChunkParsingUtils.cs
+++ b/src/ImageSharp/Formats/Webp/WebpChunkParsingUtils.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers.Binary;
using SixLabors.ImageSharp.Formats.Webp.BitReader;
diff --git a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
index 29be86e22f..83298237dd 100644
--- a/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Webp/WebpDecoderCore.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using System.Buffers;
using System.Buffers.Binary;
@@ -44,32 +43,27 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Gets the decoded by this decoder instance.
///
- private ImageMetadata metadata;
+ private ImageMetadata? metadata;
///
/// Gets or sets the alpha data, if an ALPH chunk is present.
///
- private IMemoryOwner alphaData;
+ private IMemoryOwner? alphaData;
///
/// Used for allocating memory during the decoding operations.
///
private readonly MemoryAllocator memoryAllocator;
- ///
- /// The stream to decode from.
- ///
- private BufferedReadStream currentStream;
-
///
/// The webp specific metadata.
///
- private WebpMetadata webpMetadata;
+ private WebpMetadata? webpMetadata;
///
/// Information about the webp image.
///
- private WebpImageInfo webImageInfo;
+ private WebpImageInfo? webImageInfo;
///
/// Initializes a new instance of the class.
@@ -88,21 +82,20 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
public DecoderOptions Options { get; }
///
- public Size Dimensions => new((int)this.webImageInfo.Width, (int)this.webImageInfo.Height);
+ public Size Dimensions => new((int)this.webImageInfo!.Width, (int)this.webImageInfo.Height);
///
public Image Decode(BufferedReadStream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel
{
- Image image = null;
+ Image? image = null;
try
{
this.metadata = new ImageMetadata();
- this.currentStream = stream;
- uint fileSize = this.ReadImageHeader();
+ uint fileSize = this.ReadImageHeader(stream);
- using (this.webImageInfo = this.ReadVp8Info())
+ using (this.webImageInfo = this.ReadVp8Info(stream))
{
if (this.webImageInfo.Features is { Animation: true })
{
@@ -131,7 +124,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
// There can be optional chunks after the image data, like EXIF and XMP.
if (this.webImageInfo.Features != null)
{
- this.ParseOptionalChunks(this.webImageInfo.Features);
+ this.ParseOptionalChunks(stream, this.webImageInfo.Features);
}
return image;
@@ -147,10 +140,8 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
public ImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{
- this.currentStream = stream;
-
- this.ReadImageHeader();
- using (this.webImageInfo = this.ReadVp8Info(true))
+ this.ReadImageHeader(stream);
+ using (this.webImageInfo = this.ReadVp8Info(stream, true))
{
return new ImageInfo(new PixelTypeInfo((int)this.webImageInfo.BitsPerPixel), (int)this.webImageInfo.Width, (int)this.webImageInfo.Height, this.metadata);
}
@@ -159,19 +150,20 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Reads and skips over the image header.
///
+ /// The stream to decode from.
/// The file size in bytes.
- private uint ReadImageHeader()
+ private uint ReadImageHeader(BufferedReadStream stream)
{
// Skip FourCC header, we already know its a RIFF file at this point.
- this.currentStream.Skip(4);
+ stream.Skip(4);
// Read file size.
// The size of the file in bytes starting at offset 8.
// The file size in the header is the total size of the chunks that follow plus 4 bytes for the ‘WEBP’ FourCC.
- uint fileSize = WebpChunkParsingUtils.ReadChunkSize(this.currentStream, this.buffer);
+ uint fileSize = WebpChunkParsingUtils.ReadChunkSize(stream, this.buffer);
// Skip 'WEBP' from the header.
- this.currentStream.Skip(4);
+ stream.Skip(4);
return fileSize;
}
@@ -179,42 +171,43 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Reads information present in the image header, about the image content and how to decode the image.
///
+ /// The stream to decode from.
/// For identify, the alpha data should not be read.
/// Information about the webp image.
- private WebpImageInfo ReadVp8Info(bool ignoreAlpha = false)
+ private WebpImageInfo ReadVp8Info(BufferedReadStream stream, bool ignoreAlpha = false)
{
this.metadata = new ImageMetadata();
this.webpMetadata = this.metadata.GetFormatMetadata(WebpFormat.Instance);
- WebpChunkType chunkType = WebpChunkParsingUtils.ReadChunkType(this.currentStream, this.buffer);
+ WebpChunkType chunkType = WebpChunkParsingUtils.ReadChunkType(stream, this.buffer);
var features = new WebpFeatures();
switch (chunkType)
{
case WebpChunkType.Vp8:
this.webpMetadata.FileFormat = WebpFileFormatType.Lossy;
- return WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, this.currentStream, this.buffer, features);
+ return WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, this.buffer, features);
case WebpChunkType.Vp8L:
this.webpMetadata.FileFormat = WebpFileFormatType.Lossless;
- return WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, this.currentStream, this.buffer, features);
+ return WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, this.buffer, features);
case WebpChunkType.Vp8X:
- WebpImageInfo webpInfos = WebpChunkParsingUtils.ReadVp8XHeader(this.currentStream, this.buffer, features);
- while (this.currentStream.Position < this.currentStream.Length)
+ WebpImageInfo webpInfos = WebpChunkParsingUtils.ReadVp8XHeader(stream, this.buffer, features);
+ while (stream.Position < stream.Length)
{
- chunkType = WebpChunkParsingUtils.ReadChunkType(this.currentStream, this.buffer);
+ chunkType = WebpChunkParsingUtils.ReadChunkType(stream, this.buffer);
if (chunkType == WebpChunkType.Vp8)
{
this.webpMetadata.FileFormat = WebpFileFormatType.Lossy;
- webpInfos = WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, this.currentStream, this.buffer, features);
+ webpInfos = WebpChunkParsingUtils.ReadVp8Header(this.memoryAllocator, stream, this.buffer, features);
}
else if (chunkType == WebpChunkType.Vp8L)
{
this.webpMetadata.FileFormat = WebpFileFormatType.Lossless;
- webpInfos = WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, this.currentStream, this.buffer, features);
+ webpInfos = WebpChunkParsingUtils.ReadVp8LHeader(this.memoryAllocator, stream, this.buffer, features);
}
else if (WebpChunkParsingUtils.IsOptionalVp8XChunk(chunkType))
{
- bool isAnimationChunk = this.ParseOptionalExtendedChunks(chunkType, features, ignoreAlpha);
+ bool isAnimationChunk = this.ParseOptionalExtendedChunks(stream, chunkType, features, ignoreAlpha);
if (isAnimationChunk)
{
return webpInfos;
@@ -223,8 +216,8 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
else
{
// Ignore unknown chunks.
- uint chunkSize = this.ReadChunkSize();
- this.currentStream.Skip((int)chunkSize);
+ uint chunkSize = this.ReadChunkSize(stream);
+ stream.Skip((int)chunkSize);
}
}
@@ -239,32 +232,33 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Parses optional VP8X chunks, which can be ICCP, XMP, ANIM or ALPH chunks.
///
+ /// The stream to decode from.
/// The chunk type.
/// The webp image features.
/// For identify, the alpha data should not be read.
/// true, if its a alpha chunk.
- private bool ParseOptionalExtendedChunks(WebpChunkType chunkType, WebpFeatures features, bool ignoreAlpha)
+ private bool ParseOptionalExtendedChunks(BufferedReadStream stream, WebpChunkType chunkType, WebpFeatures features, bool ignoreAlpha)
{
switch (chunkType)
{
case WebpChunkType.Iccp:
- this.ReadIccProfile();
+ this.ReadIccProfile(stream);
break;
case WebpChunkType.Exif:
- this.ReadExifProfile();
+ this.ReadExifProfile(stream);
break;
case WebpChunkType.Xmp:
- this.ReadXmpProfile();
+ this.ReadXmpProfile(stream);
break;
case WebpChunkType.AnimationParameter:
- this.ReadAnimationParameters(features);
+ this.ReadAnimationParameters(stream, features);
return true;
case WebpChunkType.Alpha:
- this.ReadAlphaData(features, ignoreAlpha);
+ this.ReadAlphaData(stream, features, ignoreAlpha);
break;
default:
WebpThrowHelper.ThrowImageFormatException("Unexpected chunk followed VP8X header");
@@ -277,32 +271,33 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Reads the optional metadata EXIF of XMP profiles, which can follow the image data.
///
+ /// The stream to decode from.
/// The webp features.
- private void ParseOptionalChunks(WebpFeatures features)
+ private void ParseOptionalChunks(BufferedReadStream stream, WebpFeatures features)
{
if (this.skipMetadata || (!features.ExifProfile && !features.XmpMetaData))
{
return;
}
- long streamLength = this.currentStream.Length;
- while (this.currentStream.Position < streamLength)
+ long streamLength = stream.Length;
+ while (stream.Position < streamLength)
{
// Read chunk header.
- WebpChunkType chunkType = this.ReadChunkType();
- if (chunkType == WebpChunkType.Exif && this.metadata.ExifProfile == null)
+ WebpChunkType chunkType = this.ReadChunkType(stream);
+ if (chunkType == WebpChunkType.Exif && this.metadata!.ExifProfile == null)
{
- this.ReadExifProfile();
+ this.ReadExifProfile(stream);
}
- else if (chunkType == WebpChunkType.Xmp && this.metadata.XmpProfile == null)
+ else if (chunkType == WebpChunkType.Xmp && this.metadata!.XmpProfile == null)
{
- this.ReadXmpProfile();
+ this.ReadXmpProfile(stream);
}
else
{
// Skip duplicate XMP or EXIF chunk.
- uint chunkLength = this.ReadChunkSize();
- this.currentStream.Skip((int)chunkLength);
+ uint chunkLength = this.ReadChunkSize(stream);
+ stream.Skip((int)chunkLength);
}
}
}
@@ -310,17 +305,18 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Reads the EXIF profile from the stream.
///
- private void ReadExifProfile()
+ /// The stream to decode from.
+ private void ReadExifProfile(BufferedReadStream stream)
{
- uint exifChunkSize = this.ReadChunkSize();
+ uint exifChunkSize = this.ReadChunkSize(stream);
if (this.skipMetadata)
{
- this.currentStream.Skip((int)exifChunkSize);
+ stream.Skip((int)exifChunkSize);
}
else
{
byte[] exifData = new byte[exifChunkSize];
- int bytesRead = this.currentStream.Read(exifData, 0, (int)exifChunkSize);
+ int bytesRead = stream.Read(exifData, 0, (int)exifChunkSize);
if (bytesRead != exifChunkSize)
{
// Ignore invalid chunk.
@@ -328,24 +324,25 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
}
var profile = new ExifProfile(exifData);
- this.metadata.ExifProfile = profile;
+ this.metadata!.ExifProfile = profile;
}
}
///
/// Reads the XMP profile the stream.
///
- private void ReadXmpProfile()
+ /// The stream to decode from.
+ private void ReadXmpProfile(BufferedReadStream stream)
{
- uint xmpChunkSize = this.ReadChunkSize();
+ uint xmpChunkSize = this.ReadChunkSize(stream);
if (this.skipMetadata)
{
- this.currentStream.Skip((int)xmpChunkSize);
+ stream.Skip((int)xmpChunkSize);
}
else
{
byte[] xmpData = new byte[xmpChunkSize];
- int bytesRead = this.currentStream.Read(xmpData, 0, (int)xmpChunkSize);
+ int bytesRead = stream.Read(xmpData, 0, (int)xmpChunkSize);
if (bytesRead != xmpChunkSize)
{
// Ignore invalid chunk.
@@ -353,24 +350,25 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
}
var profile = new XmpProfile(xmpData);
- this.metadata.XmpProfile = profile;
+ this.metadata!.XmpProfile = profile;
}
}
///
/// Reads the ICCP chunk from the stream.
///
- private void ReadIccProfile()
+ /// The stream to decode from.
+ private void ReadIccProfile(BufferedReadStream stream)
{
- uint iccpChunkSize = this.ReadChunkSize();
+ uint iccpChunkSize = this.ReadChunkSize(stream);
if (this.skipMetadata)
{
- this.currentStream.Skip((int)iccpChunkSize);
+ stream.Skip((int)iccpChunkSize);
}
else
{
byte[] iccpData = new byte[iccpChunkSize];
- int bytesRead = this.currentStream.Read(iccpData, 0, (int)iccpChunkSize);
+ int bytesRead = stream.Read(iccpData, 0, (int)iccpChunkSize);
if (bytesRead != iccpChunkSize)
{
WebpThrowHelper.ThrowInvalidImageContentException("Not enough data to read the iccp chunk");
@@ -379,7 +377,7 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
var profile = new IccProfile(iccpData);
if (profile.CheckIsValid())
{
- this.metadata.IccProfile = profile;
+ this.metadata!.IccProfile = profile;
}
}
}
@@ -387,17 +385,18 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Reads the animation parameters chunk from the stream.
///
+ /// The stream to decode from.
/// The webp features.
- private void ReadAnimationParameters(WebpFeatures features)
+ private void ReadAnimationParameters(BufferedReadStream stream, WebpFeatures features)
{
features.Animation = true;
- uint animationChunkSize = WebpChunkParsingUtils.ReadChunkSize(this.currentStream, this.buffer);
- byte blue = (byte)this.currentStream.ReadByte();
- byte green = (byte)this.currentStream.ReadByte();
- byte red = (byte)this.currentStream.ReadByte();
- byte alpha = (byte)this.currentStream.ReadByte();
+ uint animationChunkSize = WebpChunkParsingUtils.ReadChunkSize(stream, this.buffer);
+ byte blue = (byte)stream.ReadByte();
+ byte green = (byte)stream.ReadByte();
+ byte red = (byte)stream.ReadByte();
+ byte alpha = (byte)stream.ReadByte();
features.AnimationBackgroundColor = new Color(new Rgba32(red, green, blue, alpha));
- int bytesRead = this.currentStream.Read(this.buffer, 0, 2);
+ int bytesRead = stream.Read(this.buffer, 0, 2);
if (bytesRead != 2)
{
WebpThrowHelper.ThrowInvalidImageContentException("Not enough data to read the animation loop count");
@@ -409,22 +408,23 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Reads the alpha data chunk data from the stream.
///
+ /// The stream to decode from.
/// The features.
/// if set to true, skips the chunk data.
- private void ReadAlphaData(WebpFeatures features, bool ignoreAlpha)
+ private void ReadAlphaData(BufferedReadStream stream, WebpFeatures features, bool ignoreAlpha)
{
- uint alphaChunkSize = WebpChunkParsingUtils.ReadChunkSize(this.currentStream, this.buffer);
+ uint alphaChunkSize = WebpChunkParsingUtils.ReadChunkSize(stream, this.buffer);
if (ignoreAlpha)
{
- this.currentStream.Skip((int)alphaChunkSize);
+ stream.Skip((int)alphaChunkSize);
return;
}
- features.AlphaChunkHeader = (byte)this.currentStream.ReadByte();
+ features.AlphaChunkHeader = (byte)stream.ReadByte();
int alphaDataSize = (int)(alphaChunkSize - 1);
this.alphaData = this.memoryAllocator.Allocate(alphaDataSize);
Span alphaData = this.alphaData.GetSpan();
- int bytesRead = this.currentStream.Read(alphaData, 0, alphaDataSize);
+ int bytesRead = stream.Read(alphaData, 0, alphaDataSize);
if (bytesRead != alphaDataSize)
{
WebpThrowHelper.ThrowInvalidImageContentException("Not enough data to read the alpha data from the stream");
@@ -434,12 +434,13 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
///
/// Identifies the chunk type from the chunk.
///
+ /// The stream to decode from.
///
/// Thrown if the input stream is not valid.
///
- private WebpChunkType ReadChunkType()
+ private WebpChunkType ReadChunkType(BufferedReadStream stream)
{
- if (this.currentStream.Read(this.buffer, 0, 4) == 4)
+ if (stream.Read(this.buffer, 0, 4) == 4)
{
var chunkType = (WebpChunkType)BinaryPrimitives.ReadUInt32BigEndian(this.buffer);
return chunkType;
@@ -452,10 +453,11 @@ internal sealed class WebpDecoderCore : IImageDecoderInternals, IDisposable
/// Reads the chunk size. If Chunk Size is odd, a single padding byte will be added to the payload,
/// so the chunk size will be increased by 1 in those cases.
///
+ /// The stream to decode from.
/// The chunk size in bytes.
- private uint ReadChunkSize()
+ private uint ReadChunkSize(BufferedReadStream stream)
{
- if (this.currentStream.Read(this.buffer, 0, 4) == 4)
+ if (stream.Read(this.buffer, 0, 4) == 4)
{
uint chunkSize = BinaryPrimitives.ReadUInt32LittleEndian(this.buffer);
return (chunkSize % 2 == 0) ? chunkSize : chunkSize + 1;
diff --git a/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs b/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs
index 68951e5ec0..8d707fed92 100644
--- a/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs
+++ b/src/ImageSharp/Formats/Webp/WebpEncoderCore.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats.Webp.Lossless;
@@ -81,7 +80,7 @@ internal sealed class WebpEncoderCore : IImageEncoderInternals
///
/// The global configuration.
///
- private Configuration configuration;
+ private Configuration? configuration;
///
/// Initializes a new instance of the class.
diff --git a/src/ImageSharp/Formats/Webp/WebpImageInfo.cs b/src/ImageSharp/Formats/Webp/WebpImageInfo.cs
index c41403211f..5f7301b262 100644
--- a/src/ImageSharp/Formats/Webp/WebpImageInfo.cs
+++ b/src/ImageSharp/Formats/Webp/WebpImageInfo.cs
@@ -1,6 +1,5 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
-#nullable disable
using SixLabors.ImageSharp.Formats.Webp.BitReader;
using SixLabors.ImageSharp.Formats.Webp.Lossy;
@@ -36,7 +35,7 @@ internal class WebpImageInfo : IDisposable
///
/// Gets or sets additional features present in a VP8X image.
///
- public WebpFeatures Features { get; set; }
+ public WebpFeatures? Features { get; set; }
///
/// Gets or sets the VP8 profile / version. Valid values are between 0 and 3. Default value will be the invalid value -1.
@@ -46,17 +45,17 @@ internal class WebpImageInfo : IDisposable
///
/// Gets or sets the VP8 frame header.
///
- public Vp8FrameHeader Vp8FrameHeader { get; set; }
+ public Vp8FrameHeader? Vp8FrameHeader { get; set; }
///
/// Gets or sets the VP8L bitreader. Will be , if its not a lossless image.
///
- public Vp8LBitReader Vp8LBitReader { get; set; }
+ public Vp8LBitReader? Vp8LBitReader { get; set; }
///
/// Gets or sets the VP8 bitreader. Will be , if its not a lossy image.
///
- public Vp8BitReader Vp8BitReader { get; set; }
+ public Vp8BitReader? Vp8BitReader { get; set; }
///
public void Dispose()
diff --git a/src/ImageSharp/Formats/Webp/WebpThrowHelper.cs b/src/ImageSharp/Formats/Webp/WebpThrowHelper.cs
index 944cefa745..c633c52738 100644
--- a/src/ImageSharp/Formats/Webp/WebpThrowHelper.cs
+++ b/src/ImageSharp/Formats/Webp/WebpThrowHelper.cs
@@ -1,15 +1,21 @@
// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
+using System.Diagnostics.CodeAnalysis;
+
namespace SixLabors.ImageSharp.Formats.Webp;
internal static class WebpThrowHelper
{
+ [DoesNotReturn]
public static void ThrowInvalidImageContentException(string errorMessage) => throw new InvalidImageContentException(errorMessage);
+ [DoesNotReturn]
public static void ThrowImageFormatException(string errorMessage) => throw new ImageFormatException(errorMessage);
+ [DoesNotReturn]
public static void ThrowNotSupportedException(string errorMessage) => throw new NotSupportedException(errorMessage);
+ [DoesNotReturn]
public static void ThrowInvalidImageDimensions(string errorMessage) => throw new InvalidImageContentException(errorMessage);
}