From 025e526fae76329dd3923ba1234ccee444ee9543 Mon Sep 17 00:00:00 2001 From: ratok-mk Date: Fri, 18 Feb 2022 18:32:22 +0100 Subject: [PATCH 1/3] Minor Optimization for DeflaterEngine and WuQuantizer --- .../Compression/Zlib/DeflaterEngine.cs | 18 +++++++++------ .../Quantization/WuQuantizer{TPixel}.cs | 22 +++++++++++-------- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs index 506b0f2c1..4e8be3c50 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs @@ -486,15 +486,16 @@ namespace SixLabors.ImageSharp.Compression.Zlib this.matchLen = Math.Max(this.matchLen, DeflaterConstants.MIN_MATCH - 1); int matchLength = this.matchLen; - if (scan + matchLength > scanMax) + int scanEndPosition = scan + matchLength; + if (scanEndPosition > scanMax) { return false; } byte* pinnedWindow = this.pinnedWindowPointer; int scanStart = this.strstart; - byte scanEnd1 = pinnedWindow[scan + matchLength - 1]; - byte scanEnd = pinnedWindow[scan + matchLength]; + byte scanEnd1 = pinnedWindow[scanEndPosition - 1]; + byte scanEnd = pinnedWindow[scanEndPosition]; // Do not waste too much time if we already have a good match: if (matchLength >= this.goodLength) @@ -508,8 +509,9 @@ namespace SixLabors.ImageSharp.Compression.Zlib match = curMatch; scan = scanStart; - if (pinnedWindow[match + matchLength] != scanEnd - || pinnedWindow[match + matchLength - 1] != scanEnd1 + int matchEndPosition = match + matchLength; + if (pinnedWindow[matchEndPosition] != scanEnd + || pinnedWindow[matchEndPosition - 1] != scanEnd1 || pinnedWindow[match] != pinnedWindow[scan] || pinnedWindow[++match] != pinnedWindow[++scan]) { @@ -685,6 +687,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib return false; } + const int windowLen = (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD; while (this.lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush) { if (this.lookahead == 0) @@ -695,7 +698,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib return false; } - if (this.strstart > (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD) + if (this.strstart > windowLen) { // slide window, as FindLongestMatch needs this. // This should only happen when flushing and the window @@ -766,6 +769,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib return false; } + const int windowLen = (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD; while (this.lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush) { if (this.lookahead == 0) @@ -783,7 +787,7 @@ namespace SixLabors.ImageSharp.Compression.Zlib return false; } - if (this.strstart >= (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD) + if (this.strstart >= windowLen) { // slide window, as FindLongestMatch needs this. // This should only happen when flushing and the window diff --git a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs index cc5329952..5c5344ab8 100644 --- a/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs +++ b/src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs @@ -176,9 +176,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization Rgba32 rgba = default; color.ToRgba32(ref rgba); - int r = rgba.R >> (8 - IndexBits); - int g = rgba.G >> (8 - IndexBits); - int b = rgba.B >> (8 - IndexBits); + const int shift = 8 - IndexBits; + int r = rgba.R >> shift; + int g = rgba.G >> shift; + int b = rgba.B >> shift; int a = rgba.A >> (8 - IndexAlphaBits); ReadOnlySpan tagSpan = this.tagsOwner.GetSpan(); @@ -413,6 +414,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization Span momentSpan = this.momentsOwner.GetSpan(); Span volumeSpan = volume.GetSpan(); Span areaSpan = area.GetSpan(); + const int indexBits2 = IndexBits * 2; + const int indexAndAlphaBits = IndexBits + IndexAlphaBits; + const int indexBitsAndAlphaBits1 = IndexBits + IndexAlphaBits + 1; int baseIndex = GetPaletteIndex(1, 0, 0, 0); for (int r = 1; r < IndexCount; r++) @@ -421,9 +425,9 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization // immediate outer loop. See https://github.com/dotnet/runtime/issues/61420 // To ensure the calculation doesn't happen repeatedly, hoist some of the calculations // in the form of ind1* manually. - int ind1R = (r << ((IndexBits * 2) + IndexAlphaBits)) + - (r << (IndexBits + IndexAlphaBits + 1)) + - (r << (IndexBits * 2)) + + int ind1R = (r << (indexBits2 + IndexAlphaBits)) + + (r << indexBitsAndAlphaBits1) + + (r << indexBits2) + (r << (IndexBits + 1)) + r; @@ -432,7 +436,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization for (int g = 1; g < IndexCount; g++) { int ind1G = ind1R + - (g << (IndexBits + IndexAlphaBits)) + + (g << indexAndAlphaBits) + (g << IndexBits) + g; int r_g = r + g; @@ -446,7 +450,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization b; Moment line = default; - + int bIndexAlphaOffset = b * IndexAlphaCount; for (int a = 1; a < IndexAlphaCount; a++) { int ind1 = ind1B + a; @@ -455,7 +459,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization areaSpan[a] += line; - int inv = (b * IndexAlphaCount) + a; + int inv = bIndexAlphaOffset + a; volumeSpan[inv] += areaSpan[a]; int ind2 = ind1 - baseIndex; From a30f40ce343d429bd31a28a88a96338f9521485a Mon Sep 17 00:00:00 2001 From: ratok-mk Date: Tue, 22 Feb 2022 17:21:36 +0100 Subject: [PATCH 2/3] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Günther Foidl --- src/ImageSharp/Compression/Zlib/DeflaterEngine.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs index 4e8be3c50..8b32ed20e 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs @@ -483,14 +483,15 @@ namespace SixLabors.ImageSharp.Compression.Zlib int niceLength = Math.Min(this.niceLength, this.lookahead); int matchStrt = this.matchStart; - this.matchLen = Math.Max(this.matchLen, DeflaterConstants.MIN_MATCH - 1); int matchLength = this.matchLen; + matchLength = Math.Max(matchLength, DeflaterConstants.MIN_MATCH - 1); + this.matchLen = matchLength; - int scanEndPosition = scan + matchLength; - if (scanEndPosition > scanMax) + if (scan > scanMax - matchLength) { return false; } + int scanEndPosition = scan + matchLength; byte* pinnedWindow = this.pinnedWindowPointer; int scanStart = this.strstart; From 0b1cf1c5117830e604b6416044703cec161a8009 Mon Sep 17 00:00:00 2001 From: ratok-mk Date: Tue, 22 Feb 2022 17:33:34 +0100 Subject: [PATCH 3/3] Update DeflaterEngine.cs Fixed CodeStyle warnings --- src/ImageSharp/Compression/Zlib/DeflaterEngine.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs index 8b32ed20e..02fa5bf58 100644 --- a/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs +++ b/src/ImageSharp/Compression/Zlib/DeflaterEngine.cs @@ -484,13 +484,14 @@ namespace SixLabors.ImageSharp.Compression.Zlib int matchStrt = this.matchStart; int matchLength = this.matchLen; - matchLength = Math.Max(matchLength, DeflaterConstants.MIN_MATCH - 1); + matchLength = Math.Max(matchLength, DeflaterConstants.MIN_MATCH - 1); this.matchLen = matchLength; if (scan > scanMax - matchLength) { return false; } + int scanEndPosition = scan + matchLength; byte* pinnedWindow = this.pinnedWindowPointer;