diff --git a/src/ImageSharp/Formats/Webp/Lossless/HTreeGroup.cs b/src/ImageSharp/Formats/Webp/Lossless/HTreeGroup.cs index a038248f1..09ceb0334 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/HTreeGroup.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/HTreeGroup.cs @@ -19,10 +19,6 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { this.HTrees = new List(WebpConstants.HuffmanCodesPerMetaCode); this.PackedTable = new HuffmanCode[packedTableSize]; - for (int i = 0; i < packedTableSize; i++) - { - this.PackedTable[i] = new HuffmanCode(); - } } /// diff --git a/src/ImageSharp/Formats/Webp/Lossless/HuffmanCode.cs b/src/ImageSharp/Formats/Webp/Lossless/HuffmanCode.cs index f75c64de1..efb928356 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/HuffmanCode.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/HuffmanCode.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// A classic way to do entropy coding where a smaller number of bits are used for more frequent codes. /// [DebuggerDisplay("BitsUsed: {BitsUsed}, Value: {Value}")] - internal class HuffmanCode + internal struct HuffmanCode { /// /// Gets or sets the number of bits used for this symbol. diff --git a/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs b/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs index 5db01ca1c..66170b85f 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs @@ -2,6 +2,7 @@ // Licensed under the Apache License, Version 2.0. using System; +using System.Runtime.CompilerServices; namespace SixLabors.ImageSharp.Formats.Webp.Lossless { @@ -307,9 +308,9 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless public static int BuildHuffmanTable(Span table, int rootBits, int[] codeLengths, int codeLengthsSize) { - Guard.MustBeGreaterThan(rootBits, 0, nameof(rootBits)); - Guard.NotNull(codeLengths, nameof(codeLengths)); - Guard.MustBeGreaterThan(codeLengthsSize, 0, nameof(codeLengthsSize)); + DebugGuard.MustBeGreaterThan(rootBits, 0, nameof(rootBits)); + DebugGuard.NotNull(codeLengths, nameof(codeLengths)); + DebugGuard.MustBeGreaterThan(codeLengthsSize, 0, nameof(codeLengthsSize)); // sorted[codeLengthsSize] is a pre-allocated array for sorting symbols by code length. int[] sorted = new int[codeLengthsSize]; @@ -467,27 +468,27 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless break; } - else if (repetitions < 11) + + if (repetitions < 11) { tokens[pos].Code = 17; tokens[pos].ExtraBits = (byte)(repetitions - 3); pos++; break; } - else if (repetitions < 139) + + if (repetitions < 139) { tokens[pos].Code = 18; tokens[pos].ExtraBits = (byte)(repetitions - 11); pos++; break; } - else - { - tokens[pos].Code = 18; - tokens[pos].ExtraBits = 0x7f; // 138 repeated 0s - pos++; - repetitions -= 138; - } + + tokens[pos].Code = 18; + tokens[pos].ExtraBits = 0x7f; // 138 repeated 0s + pos++; + repetitions -= 138; } return pos; @@ -519,20 +520,19 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless break; } - else if (repetitions < 7) + + if (repetitions < 7) { tokens[pos].Code = 16; tokens[pos].ExtraBits = (byte)(repetitions - 3); pos++; break; } - else - { - tokens[pos].Code = 16; - tokens[pos].ExtraBits = 3; - pos++; - repetitions -= 6; - } + + tokens[pos].Code = 16; + tokens[pos].ExtraBits = 3; + pos++; + repetitions -= 6; } return pos; @@ -541,7 +541,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// /// Get the actual bit values for a tree of bit depths. /// - /// The hiffman tree. + /// The huffman tree. private static void ConvertBitDepthsToSymbols(HuffmanTreeCode tree) { // 0 bit-depth means that the symbol does not exist. @@ -628,7 +628,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// private static void ReplicateValue(Span table, int step, int end, HuffmanCode code) { - Guard.IsTrue(end % step == 0, nameof(end), "end must be a multiple of step"); + DebugGuard.IsTrue(end % step == 0, nameof(end), "end must be a multiple of step"); do { @@ -656,6 +656,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless /// /// Heuristics for selecting the stride ranges to collapse. /// + [MethodImpl(InliningOptions.ShortMethod)] private static bool ValuesShouldBeCollapsedToStrideAverage(int a, int b) => Math.Abs(a - b) < 4; } } diff --git a/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs b/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs index 4f7a4eb3d..82fd13c7d 100644 --- a/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs +++ b/src/ImageSharp/Formats/Webp/Lossless/WebpLosslessDecoder.cs @@ -834,10 +834,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless private void BuildPackedTable(HTreeGroup hTreeGroup) { - for (uint code = 0; code < HuffmanUtils.HuffmanPackedTableSize; ++code) + for (uint code = 0; code < HuffmanUtils.HuffmanPackedTableSize; code++) { uint bits = code; - HuffmanCode huff = hTreeGroup.PackedTable[bits]; + ref HuffmanCode huff = ref hTreeGroup.PackedTable[bits]; HuffmanCode hCode = hTreeGroup.HTrees[HuffIndex.Green][bits]; if (hCode.Value >= WebpConstants.NumLiteralCodes) { @@ -848,10 +848,10 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless { huff.BitsUsed = 0; huff.Value = 0; - bits >>= AccumulateHCode(hCode, 8, huff); - bits >>= AccumulateHCode(hTreeGroup.HTrees[HuffIndex.Red][bits], 16, huff); - bits >>= AccumulateHCode(hTreeGroup.HTrees[HuffIndex.Blue][bits], 0, huff); - bits >>= AccumulateHCode(hTreeGroup.HTrees[HuffIndex.Alpha][bits], 24, huff); + bits >>= AccumulateHCode(hCode, 8, ref huff); + bits >>= AccumulateHCode(hTreeGroup.HTrees[HuffIndex.Red][bits], 16, ref huff); + bits >>= AccumulateHCode(hTreeGroup.HTrees[HuffIndex.Blue][bits], 0, ref huff); + bits >>= AccumulateHCode(hTreeGroup.HTrees[HuffIndex.Alpha][bits], 24, ref huff); } } } @@ -992,7 +992,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless } [MethodImpl(InliningOptions.ShortMethod)] - private static int AccumulateHCode(HuffmanCode hCode, int shift, HuffmanCode huff) + private static int AccumulateHCode(HuffmanCode hCode, int shift, ref HuffmanCode huff) { huff.BitsUsed += hCode.BitsUsed; huff.Value |= hCode.Value << shift; diff --git a/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs index 5306a8c78..f7eef0d85 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/ColorSpaceTransformUtilsTests.cs @@ -5,7 +5,7 @@ using SixLabors.ImageSharp.Formats.Webp.Lossless; using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; -namespace SixLabors.ImageSharp.Tests.Formats.WebP +namespace SixLabors.ImageSharp.Tests.Formats.Webp { [Trait("Format", "Webp")] public class ColorSpaceTransformUtilsTests diff --git a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs index 69a24843c..907b18300 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/LossyUtilsTests.cs @@ -6,7 +6,7 @@ using SixLabors.ImageSharp.Formats.Webp.Lossy; using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; -namespace SixLabors.ImageSharp.Tests.Formats.WebP +namespace SixLabors.ImageSharp.Tests.Formats.Webp { [Trait("Format", "Webp")] public class LossyUtilsTests diff --git a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs index 55738199b..80b5f0a53 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/QuantEncTests.cs @@ -6,7 +6,7 @@ using SixLabors.ImageSharp.Formats.Webp.Lossy; using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; -namespace SixLabors.ImageSharp.Tests.Formats.WebP +namespace SixLabors.ImageSharp.Tests.Formats.Webp { [Trait("Format", "Webp")] public class QuantEncTests diff --git a/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs b/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs index 17c9beb9b..6bcb4f21f 100644 --- a/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs +++ b/tests/ImageSharp.Tests/Formats/WebP/Vp8EncodingTests.cs @@ -6,7 +6,7 @@ using SixLabors.ImageSharp.Formats.Webp.Lossy; using SixLabors.ImageSharp.Tests.TestUtilities; using Xunit; -namespace SixLabors.ImageSharp.Tests.Formats.WebP +namespace SixLabors.ImageSharp.Tests.Formats.Webp { [Trait("Format", "Webp")] public class Vp8EncodingTests