Skip to content

Commit 63829e8

Browse files
Remove more allocations and add tasks.
1 parent 3fabb76 commit 63829e8

File tree

3 files changed

+25
-28
lines changed

3 files changed

+25
-28
lines changed

src/ImageSharp/Formats/Webp/Lossless/BackwardReferenceEncoder.cs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ public static Vp8LBackwardRefs GetBackwardReferences(
5252
Vp8LHashChain? hashChainBox = null;
5353
Vp8LStreaks stats = new();
5454
Vp8LBitEntropy bitsEntropy = new();
55+
56+
ColorCache[] colorCache = new ColorCache[WebpConstants.MaxColorCacheBits + 1];
5557
for (int lz77Type = 1; lz77TypesToTry > 0; lz77TypesToTry &= ~lz77Type, lz77Type <<= 1)
5658
{
5759
int cacheBitsTmp = cacheBitsInitial;
@@ -76,7 +78,7 @@ public static Vp8LBackwardRefs GetBackwardReferences(
7678
}
7779

7880
// Next, try with a color cache and update the references.
79-
cacheBitsTmp = CalculateBestCacheSize(memoryAllocator, bgra, quality, worst, cacheBitsTmp);
81+
cacheBitsTmp = CalculateBestCacheSize(memoryAllocator, colorCache, bgra, quality, worst, cacheBitsTmp);
8082
if (cacheBitsTmp > 0)
8183
{
8284
BackwardRefsWithLocalCache(bgra, cacheBitsTmp, worst);
@@ -123,6 +125,7 @@ public static Vp8LBackwardRefs GetBackwardReferences(
123125
/// <returns>Best cache size.</returns>
124126
private static int CalculateBestCacheSize(
125127
MemoryAllocator memoryAllocator,
128+
Span<ColorCache> colorCache,
126129
ReadOnlySpan<uint> bgra,
127130
uint quality,
128131
Vp8LBackwardRefs refs,
@@ -138,12 +141,8 @@ private static int CalculateBestCacheSize(
138141
double entropyMin = MaxEntropy;
139142
int pos = 0;
140143

141-
// TODO: Pass from outer loop and clear.
142-
ColorCache[] colorCache = new ColorCache[WebpConstants.MaxColorCacheBits + 1];
143-
144-
// TODO: Use fixed size.
145-
using Vp8LHistogramSet histos = new(memoryAllocator, WebpConstants.MaxColorCacheBits + 1, 0);
146-
for (int i = 0; i <= WebpConstants.MaxColorCacheBits; i++)
144+
using Vp8LHistogramSet histos = new(memoryAllocator, colorCache.Length, 0);
145+
for (int i = 0; i < colorCache.Length; i++)
147146
{
148147
histos[i].PaletteCodeBits = i;
149148
colorCache[i] = new ColorCache(i);
@@ -448,12 +447,12 @@ private static void AddSingleLiteralWithCostModel(
448447
int ix = useColorCache ? colorCache!.Contains(color) : -1;
449448
if (ix >= 0)
450449
{
451-
double mul0 = 0.68;
450+
const double mul0 = 0.68;
452451
costVal += costModel.GetCacheCost((uint)ix) * mul0;
453452
}
454453
else
455454
{
456-
double mul1 = 0.82;
455+
const double mul1 = 0.82;
457456
if (useColorCache)
458457
{
459458
colorCache!.Insert(color);
@@ -700,10 +699,8 @@ private static void BackwardReferencesLz77Box(int xSize, int ySize, ReadOnlySpan
700699
bestLength = MaxLength;
701700
break;
702701
}
703-
else
704-
{
705-
bestLength = currLength;
706-
}
702+
703+
bestLength = currLength;
707704
}
708705
}
709706
}

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

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the Six Labors Split License.
33
#nullable disable
44

5+
using System.Buffers;
56
using System.Runtime.CompilerServices;
67
using SixLabors.ImageSharp.Memory;
78

@@ -45,9 +46,9 @@ public static void GetHistoImageSymbols(
4546
int imageHistoRawSize = histoXSize * histoYSize;
4647
const int entropyCombineNumBins = BinSize;
4748

48-
// TODO: Allocations!
49-
ushort[] mapTmp = new ushort[imageHistoRawSize];
50-
ushort[] clusterMappings = new ushort[imageHistoRawSize];
49+
using IMemoryOwner<ushort> tmp = memoryAllocator.Allocate<ushort>(imageHistoRawSize * 2, AllocationOptions.Clean);
50+
Span<ushort> mapTmp = tmp.Slice(0, imageHistoRawSize);
51+
Span<ushort> clusterMappings = tmp.Slice(imageHistoRawSize, imageHistoRawSize);
5152

5253
using Vp8LHistogramSet origHisto = new(memoryAllocator, imageHistoRawSize, cacheBits);
5354

@@ -60,13 +61,12 @@ public static void GetHistoImageSymbols(
6061
bool entropyCombine = numUsed > entropyCombineNumBins * 2 && quality < 100;
6162
if (entropyCombine)
6263
{
63-
ushort[] binMap = mapTmp;
6464
int numClusters = numUsed;
6565
double combineCostFactor = GetCombineCostFactor(imageHistoRawSize, quality);
66-
HistogramAnalyzeEntropyBin(imageHisto, binMap);
66+
HistogramAnalyzeEntropyBin(imageHisto, mapTmp);
6767

6868
// Collapse histograms with similar entropy.
69-
HistogramCombineEntropyBin(imageHisto, histogramSymbols, clusterMappings, tmpHisto, binMap, entropyCombineNumBins, combineCostFactor);
69+
HistogramCombineEntropyBin(imageHisto, histogramSymbols, clusterMappings, tmpHisto, mapTmp, entropyCombineNumBins, combineCostFactor);
7070

7171
OptimizeHistogramSymbols(clusterMappings, numClusters, mapTmp, histogramSymbols);
7272
}
@@ -128,7 +128,7 @@ private static void HistogramBuild(
128128
/// Partition histograms to different entropy bins for three dominant (literal,
129129
/// red and blue) symbol costs and compute the histogram aggregate bitCost.
130130
/// </summary>
131-
private static void HistogramAnalyzeEntropyBin(Vp8LHistogramSet histograms, ushort[] binMap)
131+
private static void HistogramAnalyzeEntropyBin(Vp8LHistogramSet histograms, Span<ushort> binMap)
132132
{
133133
int histoSize = histograms.Count;
134134
DominantCostRange costRange = new();
@@ -198,9 +198,9 @@ private static int HistogramCopyAndAnalyze(
198198
private static void HistogramCombineEntropyBin(
199199
Vp8LHistogramSet histograms,
200200
Span<ushort> clusters,
201-
ushort[] clusterMappings,
201+
Span<ushort> clusterMappings,
202202
Vp8LHistogram curCombo,
203-
ushort[] binMap,
203+
ReadOnlySpan<ushort> binMap,
204204
int numBins,
205205
double combineCostFactor)
206206
{
@@ -276,7 +276,7 @@ private static void HistogramCombineEntropyBin(
276276
/// Given a Histogram set, the mapping of clusters 'clusterMapping' and the
277277
/// current assignment of the cells in 'symbols', merge the clusters and assign the smallest possible clusters values.
278278
/// </summary>
279-
private static void OptimizeHistogramSymbols(ushort[] clusterMappings, int numClusters, ushort[] clusterMappingsTmp, Span<ushort> symbols)
279+
private static void OptimizeHistogramSymbols(Span<ushort> clusterMappings, int numClusters, Span<ushort> clusterMappingsTmp, Span<ushort> symbols)
280280
{
281281
bool doContinue = true;
282282

@@ -303,7 +303,7 @@ private static void OptimizeHistogramSymbols(ushort[] clusterMappings, int numCl
303303

304304
// Create a mapping from a cluster id to its minimal version.
305305
int clusterMax = 0;
306-
clusterMappingsTmp.AsSpan().Clear();
306+
clusterMappingsTmp.Clear();
307307

308308
// Re-map the ids.
309309
for (int i = 0; i < symbols.Length; i++)
@@ -515,7 +515,6 @@ private static void HistogramCombineGreedy(Vp8LHistogramSet histograms)
515515
histograms.DisposeAt(idx2);
516516

517517
// Remove pairs intersecting the just combined best pair.
518-
// TODO: Reversing this will avoid the need to remove from the end of the list.
519518
for (int i = 0; i < histoPriorityList.Count;)
520519
{
521520
HistogramPair p = histoPriorityList[i];

src/ImageSharp/Formats/Webp/Lossless/Vp8LEncoder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ private void StoreHuffmanCode(Span<HuffmanTree> huffTree, HuffmanTreeToken[] tok
885885

886886
private void StoreFullHuffmanCode(Span<HuffmanTree> huffTree, HuffmanTreeToken[] tokens, HuffmanTreeCode tree)
887887
{
888-
// TODO: Allocations.
888+
// TODO: Allocations. This method is called in a loop.
889889
int i;
890890
byte[] codeLengthBitDepth = new byte[WebpConstants.CodeLengthCodes];
891891
short[] codeLengthBitDepthSymbols = new short[WebpConstants.CodeLengthCodes];
@@ -1628,6 +1628,7 @@ private static void GetHuffBitLengthsAndCodes(Vp8LHistogramSet histogramImage, H
16281628
}
16291629
}
16301630

1631+
// TODO: Allocations.
16311632
int end = 5 * histogramImage.Count;
16321633
for (int i = 0; i < end; i++)
16331634
{
@@ -1641,9 +1642,9 @@ private static void GetHuffBitLengthsAndCodes(Vp8LHistogramSet histogramImage, H
16411642
}
16421643

16431644
// Create Huffman trees.
1644-
// TODO: Allocations. Size here has a max and can be sliced.
1645+
// TODO: Allocations.
16451646
bool[] bufRle = new bool[maxNumSymbols];
1646-
Span<HuffmanTree> huffTree = stackalloc HuffmanTree[3 * maxNumSymbols];
1647+
HuffmanTree[] huffTree = new HuffmanTree[3 * maxNumSymbols];
16471648

16481649
for (int i = 0; i < histogramImage.Count; i++)
16491650
{

0 commit comments

Comments
 (0)