Browse Source

Merge pull request #1818 from kunalspathak/3DMoments

Hoist some of the calculations from loops of 3DMoments()
pull/1828/head
James Jackson-South 4 years ago
committed by GitHub
parent
commit
a39fe4c07c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs
  2. 2
      tests/ImageSharp.Benchmarks/Codecs/EncodeIndexedPng.cs

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

@ -417,19 +417,40 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
for (int r = 1; r < IndexCount; r++)
{
// Currently, RyuJIT hoists the invariants of multi-level nested loop only to the
// 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)) +
(r << (IndexBits + 1)) +
r;
volumeSpan.Clear();
for (int g = 1; g < IndexCount; g++)
{
int ind1G = ind1R +
(g << (IndexBits + IndexAlphaBits)) +
(g << IndexBits) +
g;
int r_g = r + g;
areaSpan.Clear();
for (int b = 1; b < IndexCount; b++)
{
int ind1B = ind1G +
((r_g + b) << IndexAlphaBits) +
b;
Moment line = default;
for (int a = 1; a < IndexAlphaCount; a++)
{
int ind1 = GetPaletteIndex(r, g, b, a);
int ind1 = ind1B + a;
line += momentSpan[ind1];
areaSpan[a] += line;
@ -628,13 +649,35 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
for (int r = cube.RMin + 1; r <= cube.RMax; r++)
{
// Currently, RyuJIT hoists the invariants of multi-level nested loop only to the
// 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)) +
(r << (IndexBits + 1)) +
r;
for (int g = cube.GMin + 1; g <= cube.GMax; g++)
{
int ind1G = ind1R +
(g << (IndexBits + IndexAlphaBits)) +
(g << IndexBits) +
g;
int r_g = r + g;
for (int b = cube.BMin + 1; b <= cube.BMax; b++)
{
int ind1B = ind1G +
((r_g + b) << IndexAlphaBits) +
b;
for (int a = cube.AMin + 1; a <= cube.AMax; a++)
{
tagSpan[GetPaletteIndex(r, g, b, a)] = label;
int index = ind1B + a;
tagSpan[index] = label;
}
}
}

2
tests/ImageSharp.Benchmarks/Codecs/EncodeIndexedPng.cs

@ -85,7 +85,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs
public void PngCoreWuNoDither()
{
using var memoryStream = new MemoryStream();
var options = new PngEncoder { Quantizer = new WuQuantizer(new QuantizerOptions { Dither = null }) };
var options = new PngEncoder { Quantizer = new WuQuantizer(new QuantizerOptions { Dither = null }), ColorType = PngColorType.Palette };
this.bmpCore.SaveAsPng(memoryStream, options);
}
}

Loading…
Cancel
Save