Browse Source

AnalyzeBestIntra4Mode for method >= 5

pull/1552/head
Brian Popow 5 years ago
parent
commit
8d7d68f626
  1. 17
      src/ImageSharp/Formats/WebP/Lossless/Vp8LHistogram.cs
  2. 58
      src/ImageSharp/Formats/WebP/Lossy/Vp8EncIterator.cs
  3. 16
      src/ImageSharp/Formats/WebP/Lossy/Vp8Encoder.cs

17
src/ImageSharp/Formats/WebP/Lossless/Vp8LHistogram.cs

@ -68,7 +68,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
this.Alpha = new uint[WebpConstants.NumLiteralCodes + 1];
this.Distance = new uint[WebpConstants.NumDistanceCodes];
var literalSize = WebpConstants.NumLiteralCodes + WebpConstants.NumLengthCodes + (1 << WebpConstants.MaxColorCacheBits);
int literalSize = WebpConstants.NumLiteralCodes + WebpConstants.NumLengthCodes + (1 << WebpConstants.MaxColorCacheBits);
this.Literal = new uint[literalSize + 1];
// 5 for literal, red, blue, alpha, distance.
@ -232,7 +232,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
public double AddThresh(Vp8LHistogram b, double costThreshold)
{
double costInitial = -this.BitCost;
this.GetCombinedHistogramEntropy(b, costThreshold, costInitial, out var cost);
this.GetCombinedHistogramEntropy(b, costThreshold, costInitial, out double cost);
return cost;
}
@ -350,6 +350,19 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossless
return alpha;
}
public void Merge(Vp8LHistogram other)
{
if (this.maxValue > other.maxValue)
{
other.maxValue = this.maxValue;
}
if (this.lastNonZero > other.lastNonZero)
{
other.lastNonZero = this.lastNonZero;
}
}
private void SetHistogramData(int[] distribution)
{
int maxValue = 0;

58
src/ImageSharp/Formats/WebP/Lossy/Vp8EncIterator.cs

@ -18,9 +18,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
public const int VOffEnc = 16 + 8;
private const int MaxIntra16Mode = 2;
private const int MaxIntra4Mode = 2;
private const int MaxUvMode = 2;
private const int MaxIntra16Mode = 2;
private const int DefaultAlpha = -1;
private readonly int mbw;
@ -373,7 +377,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
{
int maxMode = MaxIntra16Mode;
int mode;
int bestAlpha = -1;
int bestAlpha = DefaultAlpha;
int bestMode = 0;
this.MakeLuma16Preds();
@ -393,9 +397,57 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
return bestAlpha;
}
public int MbAnalyzeBestIntra4Mode(int bestAlpha)
{
byte[] modes = new byte[16];
int maxMode = MaxIntra4Mode;
int i4Alpha;
var totalHisto = new Vp8LHistogram();
int curHisto = 0;
this.StartI4();
do
{
int mode;
int bestModeAlpha = DefaultAlpha;
var histos = new Vp8LHistogram[2];
Span<byte> src = this.YuvIn.AsSpan(YOffEnc + WebpLookupTables.Vp8Scan[this.I4]);
this.MakeIntra4Preds();
for (mode = 0; mode < maxMode; ++mode)
{
int alpha;
histos[curHisto] = new Vp8LHistogram();
histos[curHisto].CollectHistogram(src, this.YuvP.AsSpan(Vp8Encoding.Vp8I4ModeOffsets[mode]), 0, 1);
alpha = histos[curHisto].GetAlpha();
if (alpha > bestModeAlpha)
{
bestModeAlpha = alpha;
modes[this.I4] = (byte)mode;
// Keep track of best histo so far.
curHisto ^= 1;
}
}
// Accumulate best histogram.
histos[curHisto ^ 1].Merge(totalHisto);
}
while (this.RotateI4(this.YuvIn.AsSpan(YOffEnc))); // Note: we reuse the original samples for predictors.
i4Alpha = totalHisto.GetAlpha();
if (i4Alpha > bestAlpha)
{
this.SetIntra4Mode(modes);
bestAlpha = i4Alpha;
}
return bestAlpha;
}
public int MbAnalyzeBestUvMode()
{
int bestAlpha = -1;
int bestAlpha = DefaultAlpha;
int smallestAlpha = 0;
int bestMode = 0;
int maxMode = MaxUvMode;

16
src/ImageSharp/Formats/WebP/Lossy/Vp8Encoder.cs

@ -850,7 +850,21 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy
it.SetSkip(false); // not skipped.
it.SetSegment(0); // default segment, spec-wise.
int bestAlpha = this.method <= 1 ? it.FastMbAnalyze(this.quality) : it.MbAnalyzeBestIntra16Mode();
int bestAlpha;
if (this.method <= 1)
{
bestAlpha = it.FastMbAnalyze(this.quality);
}
else
{
bestAlpha = it.MbAnalyzeBestIntra16Mode();
if (this.method >= 5)
{
// We go and make a fast decision for intra4/intra16.
// It's usually not a good and definitive pick, but helps seeding the stats about level bit-cost.
bestAlpha = it.MbAnalyzeBestIntra4Mode(bestAlpha);
}
}
bestUvAlpha = it.MbAnalyzeBestUvMode();

Loading…
Cancel
Save