Browse Source

Merge branch 'master' into bp/ColorBlueTransformAvx

pull/1824/head
Brian Popow 4 years ago
committed by GitHub
parent
commit
37189bfa78
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
  2. 4
      src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs
  3. 12
      src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs
  4. 2
      src/ImageSharp/Formats/Webp/Lossless/CostModel.cs
  5. 2
      src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs
  6. 2
      src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs
  7. 10
      src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs
  8. 8
      src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs
  9. 2
      src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs
  10. 47
      src/ImageSharp/Processing/Processors/Quantization/WuQuantizer{TPixel}.cs
  11. 2
      tests/ImageSharp.Benchmarks/Codecs/EncodeIndexedPng.cs

4
src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs

@ -288,8 +288,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// <param name="componentCount">The number of components to write.</param>
private void WriteDefineHuffmanTables(int componentCount)
{
// This uses a C#'s compiler optimization that refers to the static data segment of the assembly,
// and doesn't incur any allocation at all.
// Table identifiers.
ReadOnlySpan<byte> headers = stackalloc byte[]
ReadOnlySpan<byte> headers = new byte[]
{
0x00,
0x10,

4
src/ImageSharp/Formats/Tiff/Compression/Compressors/TiffLzwEncoder.cs

@ -256,8 +256,8 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Compressors
private void ResetTables()
{
this.children.GetSpan().Fill(0);
this.siblings.GetSpan().Fill(0);
this.children.GetSpan().Clear();
this.siblings.GetSpan().Clear();
this.bitsPerCode = MinBits;
this.maxCode = MaxValue(this.bitsPerCode);
this.nextValidCode = EoiCode + 1;

12
src/ImageSharp/Formats/Tiff/Compression/Decompressors/T6TiffCompression.cs

@ -64,7 +64,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
uint bitsWritten = 0;
for (int y = 0; y < height; y++)
{
scanLine.Fill(0);
scanLine.Clear();
Decode2DScanline(bitReader, this.isWhiteZero, referenceScanLine, scanLine);
bitsWritten = this.WriteScanLine(buffer, scanLine, bitsWritten);
@ -116,7 +116,15 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors
{
// If a TIFF reader encounters EOFB before the expected number of lines has been extracted,
// it is appropriate to assume that the missing rows consist entirely of white pixels.
scanline.Fill(whiteIsZero ? (byte)0 : (byte)255);
if (whiteIsZero)
{
scanline.Clear();
}
else
{
scanline.Fill((byte)255);
}
break;
}

2
src/ImageSharp/Formats/Webp/Lossless/CostModel.cs

@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
if (nonzeros <= 1)
{
output.AsSpan(0, numSymbols).Fill(0);
output.AsSpan(0, numSymbols).Clear();
}
else
{

2
src/ImageSharp/Formats/Webp/Lossless/HistogramEncoder.cs

@ -287,7 +287,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
// Create a mapping from a cluster id to its minimal version.
int clusterMax = 0;
clusterMappingsTmp.AsSpan().Fill(0);
clusterMappingsTmp.AsSpan().Clear();
// Re-map the ids.
for (int i = 0; i < symbols.Length; i++)

2
src/ImageSharp/Formats/Webp/Lossless/HuffmanUtils.cs

@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
public static void CreateHuffmanTree(uint[] histogram, int treeDepthLimit, bool[] bufRle, HuffmanTree[] huffTree, HuffmanTreeCode huffCode)
{
int numSymbols = huffCode.NumSymbols;
bufRle.AsSpan().Fill(false);
bufRle.AsSpan().Clear();
OptimizeHuffmanForRle(numSymbols, bufRle, histogram);
GenerateOptimalTree(huffTree, histogram, numSymbols, treeDepthLimit, huffCode.CodeLengths);

10
src/ImageSharp/Formats/Webp/Lossless/Vp8LHistogram.cs

@ -320,7 +320,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
else
{
output.Literal.AsSpan(0, literalSize).Fill(0);
output.Literal.AsSpan(0, literalSize).Clear();
}
}
@ -343,7 +343,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
else
{
output.Red.AsSpan(0, size).Fill(0);
output.Red.AsSpan(0, size).Clear();
}
}
@ -366,7 +366,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
else
{
output.Blue.AsSpan(0, size).Fill(0);
output.Blue.AsSpan(0, size).Clear();
}
}
@ -389,7 +389,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
else
{
output.Alpha.AsSpan(0, size).Fill(0);
output.Alpha.AsSpan(0, size).Clear();
}
}
@ -412,7 +412,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
}
else
{
output.Distance.AsSpan(0, size).Fill(0);
output.Distance.AsSpan(0, size).Clear();
}
}

8
src/ImageSharp/Formats/Webp/Lossy/Vp8EncIterator.cs

@ -911,7 +911,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
this.LeftNz[8] = 0;
this.LeftDerr.AsSpan().Fill(0);
this.LeftDerr.AsSpan().Clear();
}
private void InitTop()
@ -919,14 +919,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
int topSize = this.mbw * 16;
this.YTop.AsSpan(0, topSize).Fill(127);
this.UvTop.AsSpan().Fill(127);
this.Nz.AsSpan().Fill(0);
this.Nz.AsSpan().Clear();
int predsW = (4 * this.mbw) + 1;
int predsH = (4 * this.mbh) + 1;
int predsSize = predsW * predsH;
this.Preds.AsSpan(predsSize + this.predsWidth, this.mbw).Fill(0);
this.Preds.AsSpan(predsSize + this.predsWidth, this.mbw).Clear();
this.TopDerr.AsSpan().Fill(0);
this.TopDerr.AsSpan().Clear();
}
private int Bit(uint nz, int n) => (nz & (1 << n)) != 0 ? 1 : 0;

2
src/ImageSharp/Formats/Webp/Lossy/Vp8Encoder.cs

@ -546,7 +546,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
int predsW = (4 * this.Mbw) + 1;
int predsH = (4 * this.Mbh) + 1;
int predsSize = predsW * predsH;
this.Preds.AsSpan(predsSize + this.PredsWidth - 4, 4).Fill(0);
this.Preds.AsSpan(predsSize + this.PredsWidth - 4, 4).Clear();
this.Nz[0] = 0; // constant
}

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