From e31f8d53cb14ae3aad0ed12f7c2bf23054b68123 Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Mon, 16 Mar 2020 14:12:15 +0100 Subject: [PATCH] Fix lossy decoding issue: return value of ParseResiduals was not used --- .../Formats/WebP/IWebPDecoderOptions.cs | 2 +- src/ImageSharp/Formats/WebP/Vp8Decoder.cs | 2 +- src/ImageSharp/Formats/WebP/Vp8FilterInfo.cs | 3 +-- .../Formats/WebP/Vp8MacroBlockData.cs | 7 +++++-- .../Formats/WebP/WebPLookupTables.cs | 1 - .../Formats/WebP/WebPLossyDecoder.cs | 20 +++++++++---------- 6 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/ImageSharp/Formats/WebP/IWebPDecoderOptions.cs b/src/ImageSharp/Formats/WebP/IWebPDecoderOptions.cs index 1ddbdbdc6d..13bf817c43 100644 --- a/src/ImageSharp/Formats/WebP/IWebPDecoderOptions.cs +++ b/src/ImageSharp/Formats/WebP/IWebPDecoderOptions.cs @@ -4,7 +4,7 @@ namespace SixLabors.ImageSharp.Formats.WebP { /// - /// Image decoder for generating an image out of a webp stream. + /// Image decoder options for generating an image out of a webp stream. /// internal interface IWebPDecoderOptions { diff --git a/src/ImageSharp/Formats/WebP/Vp8Decoder.cs b/src/ImageSharp/Formats/WebP/Vp8Decoder.cs index f47100ef3a..49d642d483 100644 --- a/src/ImageSharp/Formats/WebP/Vp8Decoder.cs +++ b/src/ImageSharp/Formats/WebP/Vp8Decoder.cs @@ -340,7 +340,7 @@ namespace SixLabors.ImageSharp.Formats.WebP info.Limit = 0; // no filtering. } - info.UseInnerFiltering = (byte)i4x4; + info.UseInnerFiltering = i4x4 is 1; } } } diff --git a/src/ImageSharp/Formats/WebP/Vp8FilterInfo.cs b/src/ImageSharp/Formats/WebP/Vp8FilterInfo.cs index 760e1b5c55..16c9d9c0e5 100644 --- a/src/ImageSharp/Formats/WebP/Vp8FilterInfo.cs +++ b/src/ImageSharp/Formats/WebP/Vp8FilterInfo.cs @@ -39,9 +39,8 @@ namespace SixLabors.ImageSharp.Formats.WebP /// /// Gets or sets a value indicating whether to do inner filtering. - /// TODO: can this be a bool? /// - public byte UseInnerFiltering { get; set; } + public bool UseInnerFiltering { get; set; } /// /// Gets or sets the high edge variance threshold in [0..2]. diff --git a/src/ImageSharp/Formats/WebP/Vp8MacroBlockData.cs b/src/ImageSharp/Formats/WebP/Vp8MacroBlockData.cs index cfac56d3c7..e0536e6b48 100644 --- a/src/ImageSharp/Formats/WebP/Vp8MacroBlockData.cs +++ b/src/ImageSharp/Formats/WebP/Vp8MacroBlockData.cs @@ -8,6 +8,9 @@ namespace SixLabors.ImageSharp.Formats.WebP /// internal class Vp8MacroBlockData { + /// + /// Initializes a new instance of the class. + /// public Vp8MacroBlockData() { this.Modes = new byte[16]; @@ -15,7 +18,7 @@ namespace SixLabors.ImageSharp.Formats.WebP } /// - /// Gets or sets the coefficient. 384 coeffs = (16+4+4) * 4*4. + /// Gets or sets the coefficients. 384 coeffs = (16+4+4) * 4*4. /// public short[] Coeffs { get; set; } @@ -38,7 +41,7 @@ namespace SixLabors.ImageSharp.Formats.WebP public uint NonZeroUv { get; set; } - public byte Skip { get; set; } + public bool Skip { get; set; } public byte Segment { get; set; } } diff --git a/src/ImageSharp/Formats/WebP/WebPLookupTables.cs b/src/ImageSharp/Formats/WebP/WebPLookupTables.cs index 26c4be7736..a2aa76999f 100644 --- a/src/ImageSharp/Formats/WebP/WebPLookupTables.cs +++ b/src/ImageSharp/Formats/WebP/WebPLookupTables.cs @@ -444,7 +444,6 @@ namespace SixLabors.ImageSharp.Formats.WebP static WebPLookupTables() { - // TODO: maybe use hashset here Abs0 = new Dictionary(); for (int i = -255; i <= 255; ++i) { diff --git a/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs b/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs index c24e60812b..db1e254fae 100644 --- a/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs +++ b/src/ImageSharp/Formats/WebP/WebPLossyDecoder.cs @@ -191,7 +191,7 @@ namespace SixLabors.ImageSharp.Formats.WebP if (dec.UseSkipProbability) { - block.Skip = (byte)this.bitReader.GetBit(dec.SkipProbability); + block.Skip = this.bitReader.GetBit(dec.SkipProbability) is 1; } block.IsI4x4 = this.bitReader.GetBit(145) is 0; @@ -488,7 +488,7 @@ namespace SixLabors.ImageSharp.Formats.WebP break; } - this.DoUVTransform(bitsUv >> 0, coeffs.AsSpan(16 * 16), uDst); + this.DoUVTransform(bitsUv, coeffs.AsSpan(16 * 16), uDst); this.DoUVTransform(bitsUv >> 8, coeffs.AsSpan(20 * 16), vDst); // Stash away top samples for next block. @@ -545,7 +545,7 @@ namespace SixLabors.ImageSharp.Formats.WebP LossyUtils.SimpleHFilter16(dec.CacheY.Memory.Span, offset, yBps, limit + 4); } - if (filterInfo.UseInnerFiltering > 0) + if (filterInfo.UseInnerFiltering) { LossyUtils.SimpleHFilter16i(dec.CacheY.Memory.Span, offset, yBps, limit); } @@ -555,7 +555,7 @@ namespace SixLabors.ImageSharp.Formats.WebP LossyUtils.SimpleVFilter16(dec.CacheY.Memory.Span, offset, yBps, limit + 4); } - if (filterInfo.UseInnerFiltering > 0) + if (filterInfo.UseInnerFiltering) { LossyUtils.SimpleVFilter16i(dec.CacheY.Memory.Span, offset, yBps, limit); } @@ -572,7 +572,7 @@ namespace SixLabors.ImageSharp.Formats.WebP LossyUtils.HFilter8(dec.CacheU.Memory.Span, dec.CacheV.Memory.Span, uvOffset, uvBps, limit + 4, iLevel, hevThresh); } - if (filterInfo.UseInnerFiltering > 0) + if (filterInfo.UseInnerFiltering) { LossyUtils.HFilter16i(dec.CacheY.Memory.Span, yOffset, yBps, limit, iLevel, hevThresh); LossyUtils.HFilter8i(dec.CacheU.Memory.Span, dec.CacheV.Memory.Span, uvOffset, uvBps, limit, iLevel, hevThresh); @@ -584,7 +584,7 @@ namespace SixLabors.ImageSharp.Formats.WebP LossyUtils.VFilter8(dec.CacheU.Memory.Span, dec.CacheV.Memory.Span, uvOffset, uvBps, limit + 4, iLevel, hevThresh); } - if (filterInfo.UseInnerFiltering > 0) + if (filterInfo.UseInnerFiltering) { LossyUtils.VFilter16i(dec.CacheY.Memory.Span, yOffset, yBps, limit, iLevel, hevThresh); LossyUtils.VFilter8i(dec.CacheU.Memory.Span, dec.CacheV.Memory.Span, uvOffset, uvBps, limit, iLevel, hevThresh); @@ -820,11 +820,11 @@ namespace SixLabors.ImageSharp.Formats.WebP Vp8MacroBlock left = dec.LeftMacroBlock; Vp8MacroBlock macroBlock = dec.CurrentMacroBlock; Vp8MacroBlockData blockData = dec.CurrentBlockData; - int skip = dec.UseSkipProbability ? blockData.Skip : 0; + bool skip = dec.UseSkipProbability ? blockData.Skip : false; - if (skip is 0) + if (!skip) { - this.ParseResiduals(dec, bitreader, macroBlock); + skip = this.ParseResiduals(dec, bitreader, macroBlock); } else { @@ -843,7 +843,7 @@ namespace SixLabors.ImageSharp.Formats.WebP { Vp8FilterInfo precomputedFilterInfo = dec.FilterStrength[blockData.Segment, blockData.IsI4x4 ? 1 : 0]; dec.FilterInfo[dec.MbX] = (Vp8FilterInfo)precomputedFilterInfo.DeepClone(); - dec.FilterInfo[dec.MbX].UseInnerFiltering |= (byte)(skip is 0 ? 1 : 0); + dec.FilterInfo[dec.MbX].UseInnerFiltering |= !skip; } }