Skip to content

Commit 6285738

Browse files
Merge pull request #2023 from ratok-mk/mk/optimize-PNG-encoding
Minor PNG Encoding Optimization for DeflaterEngine and WuQuantizer
2 parents 14418c1 + f774f45 commit 6285738

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

src/ImageSharp/Compression/Zlib/DeflaterEngine.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -483,18 +483,21 @@ private bool FindLongestMatch(int curMatch)
483483
int niceLength = Math.Min(this.niceLength, this.lookahead);
484484

485485
int matchStrt = this.matchStart;
486-
this.matchLen = Math.Max(this.matchLen, DeflaterConstants.MIN_MATCH - 1);
487486
int matchLength = this.matchLen;
487+
matchLength = Math.Max(matchLength, DeflaterConstants.MIN_MATCH - 1);
488+
this.matchLen = matchLength;
488489

489-
if (scan + matchLength > scanMax)
490+
if (scan > scanMax - matchLength)
490491
{
491492
return false;
492493
}
493494

495+
int scanEndPosition = scan + matchLength;
496+
494497
byte* pinnedWindow = this.pinnedWindowPointer;
495498
int scanStart = this.strstart;
496-
byte scanEnd1 = pinnedWindow[scan + matchLength - 1];
497-
byte scanEnd = pinnedWindow[scan + matchLength];
499+
byte scanEnd1 = pinnedWindow[scanEndPosition - 1];
500+
byte scanEnd = pinnedWindow[scanEndPosition];
498501

499502
// Do not waste too much time if we already have a good match:
500503
if (matchLength >= this.goodLength)
@@ -508,8 +511,9 @@ private bool FindLongestMatch(int curMatch)
508511
match = curMatch;
509512
scan = scanStart;
510513

511-
if (pinnedWindow[match + matchLength] != scanEnd
512-
|| pinnedWindow[match + matchLength - 1] != scanEnd1
514+
int matchEndPosition = match + matchLength;
515+
if (pinnedWindow[matchEndPosition] != scanEnd
516+
|| pinnedWindow[matchEndPosition - 1] != scanEnd1
513517
|| pinnedWindow[match] != pinnedWindow[scan]
514518
|| pinnedWindow[++match] != pinnedWindow[++scan])
515519
{
@@ -685,6 +689,7 @@ private bool DeflateFast(bool flush, bool finish)
685689
return false;
686690
}
687691

692+
const int windowLen = (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD;
688693
while (this.lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush)
689694
{
690695
if (this.lookahead == 0)
@@ -695,7 +700,7 @@ private bool DeflateFast(bool flush, bool finish)
695700
return false;
696701
}
697702

698-
if (this.strstart > (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD)
703+
if (this.strstart > windowLen)
699704
{
700705
// slide window, as FindLongestMatch needs this.
701706
// This should only happen when flushing and the window
@@ -766,6 +771,7 @@ private bool DeflateSlow(bool flush, bool finish)
766771
return false;
767772
}
768773

774+
const int windowLen = (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD;
769775
while (this.lookahead >= DeflaterConstants.MIN_LOOKAHEAD || flush)
770776
{
771777
if (this.lookahead == 0)
@@ -783,7 +789,7 @@ private bool DeflateSlow(bool flush, bool finish)
783789
return false;
784790
}
785791

786-
if (this.strstart >= (2 * DeflaterConstants.WSIZE) - DeflaterConstants.MIN_LOOKAHEAD)
792+
if (this.strstart >= windowLen)
787793
{
788794
// slide window, as FindLongestMatch needs this.
789795
// This should only happen when flushing and the window

src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -176,9 +176,10 @@ public readonly byte GetQuantizedColor(TPixel color, out TPixel match)
176176
Rgba32 rgba = default;
177177
color.ToRgba32(ref rgba);
178178

179-
int r = rgba.R >> (8 - IndexBits);
180-
int g = rgba.G >> (8 - IndexBits);
181-
int b = rgba.B >> (8 - IndexBits);
179+
const int shift = 8 - IndexBits;
180+
int r = rgba.R >> shift;
181+
int g = rgba.G >> shift;
182+
int b = rgba.B >> shift;
182183
int a = rgba.A >> (8 - IndexAlphaBits);
183184

184185
ReadOnlySpan<byte> tagSpan = this.tagsOwner.GetSpan();
@@ -413,6 +414,9 @@ private void Get3DMoments(MemoryAllocator allocator)
413414
Span<Moment> momentSpan = this.momentsOwner.GetSpan();
414415
Span<Moment> volumeSpan = volume.GetSpan();
415416
Span<Moment> areaSpan = area.GetSpan();
417+
const int indexBits2 = IndexBits * 2;
418+
const int indexAndAlphaBits = IndexBits + IndexAlphaBits;
419+
const int indexBitsAndAlphaBits1 = IndexBits + IndexAlphaBits + 1;
416420
int baseIndex = GetPaletteIndex(1, 0, 0, 0);
417421

418422
for (int r = 1; r < IndexCount; r++)
@@ -421,9 +425,9 @@ private void Get3DMoments(MemoryAllocator allocator)
421425
// immediate outer loop. See https://github.com/dotnet/runtime/issues/61420
422426
// To ensure the calculation doesn't happen repeatedly, hoist some of the calculations
423427
// in the form of ind1* manually.
424-
int ind1R = (r << ((IndexBits * 2) + IndexAlphaBits)) +
425-
(r << (IndexBits + IndexAlphaBits + 1)) +
426-
(r << (IndexBits * 2)) +
428+
int ind1R = (r << (indexBits2 + IndexAlphaBits)) +
429+
(r << indexBitsAndAlphaBits1) +
430+
(r << indexBits2) +
427431
(r << (IndexBits + 1)) +
428432
r;
429433

@@ -432,7 +436,7 @@ private void Get3DMoments(MemoryAllocator allocator)
432436
for (int g = 1; g < IndexCount; g++)
433437
{
434438
int ind1G = ind1R +
435-
(g << (IndexBits + IndexAlphaBits)) +
439+
(g << indexAndAlphaBits) +
436440
(g << IndexBits) +
437441
g;
438442
int r_g = r + g;
@@ -446,7 +450,7 @@ private void Get3DMoments(MemoryAllocator allocator)
446450
b;
447451

448452
Moment line = default;
449-
453+
int bIndexAlphaOffset = b * IndexAlphaCount;
450454
for (int a = 1; a < IndexAlphaCount; a++)
451455
{
452456
int ind1 = ind1B + a;
@@ -455,7 +459,7 @@ private void Get3DMoments(MemoryAllocator allocator)
455459

456460
areaSpan[a] += line;
457461

458-
int inv = (b * IndexAlphaCount) + a;
462+
int inv = bIndexAlphaOffset + a;
459463
volumeSpan[inv] += areaSpan[a];
460464

461465
int ind2 = ind1 - baseIndex;

0 commit comments

Comments
 (0)