|
|
|
@ -115,13 +115,13 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy |
|
|
|
this.Width = width; |
|
|
|
this.Height = height; |
|
|
|
this.quality = Numerics.Clamp(quality, 0, 100); |
|
|
|
this.method = (WebpEncodingMethod)Numerics.Clamp((int)method, 0, 6); |
|
|
|
this.method = method; |
|
|
|
this.entropyPasses = Numerics.Clamp(entropyPasses, 1, 10); |
|
|
|
this.filterStrength = Numerics.Clamp(filterStrength, 0, 100); |
|
|
|
this.spatialNoiseShaping = Numerics.Clamp(spatialNoiseShaping, 0, 100); |
|
|
|
this.rdOptLevel = method is WebpEncodingMethod.BestQuality ? Vp8RdLevel.RdOptTrellisAll |
|
|
|
: (int)method >= 5 ? Vp8RdLevel.RdOptTrellis |
|
|
|
: (int)method >= 3 ? Vp8RdLevel.RdOptBasic |
|
|
|
: method >= WebpEncodingMethod.Level5 ? Vp8RdLevel.RdOptTrellis |
|
|
|
: method >= WebpEncodingMethod.Level3 ? Vp8RdLevel.RdOptBasic |
|
|
|
: Vp8RdLevel.RdOptNone; |
|
|
|
|
|
|
|
int pixelCount = width * height; |
|
|
|
@ -371,7 +371,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy |
|
|
|
bool doSearch = targetSize > 0 || targetPsnr > 0; |
|
|
|
bool fastProbe = (this.method == 0 || this.method == WebpEncodingMethod.Level3) && !doSearch; |
|
|
|
int numPassLeft = this.entropyPasses; |
|
|
|
Vp8RdLevel rdOpt = (int)this.method >= 3 || doSearch ? Vp8RdLevel.RdOptBasic : Vp8RdLevel.RdOptNone; |
|
|
|
Vp8RdLevel rdOpt = this.method >= WebpEncodingMethod.Level3 || doSearch ? Vp8RdLevel.RdOptBasic : Vp8RdLevel.RdOptNone; |
|
|
|
int nbMbs = this.Mbw * this.Mbh; |
|
|
|
|
|
|
|
var stats = new PassStats(targetSize, targetPsnr, QMin, QMax, this.quality); |
|
|
|
@ -799,7 +799,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy |
|
|
|
|
|
|
|
private void SetupMatrices(Vp8SegmentInfo[] dqm) |
|
|
|
{ |
|
|
|
int tlambdaScale = (int)this.method >= 4 ? this.spatialNoiseShaping : 0; |
|
|
|
int tlambdaScale = this.method >= WebpEncodingMethod.Default ? this.spatialNoiseShaping : 0; |
|
|
|
for (int i = 0; i < dqm.Length; i++) |
|
|
|
{ |
|
|
|
Vp8SegmentInfo m = dqm[i]; |
|
|
|
@ -870,14 +870,14 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy |
|
|
|
it.SetSegment(0); // default segment, spec-wise.
|
|
|
|
|
|
|
|
int bestAlpha; |
|
|
|
if ((int)this.method <= 1) |
|
|
|
if (this.method <= WebpEncodingMethod.Level1) |
|
|
|
{ |
|
|
|
bestAlpha = it.FastMbAnalyze(this.quality); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
bestAlpha = it.MbAnalyzeBestIntra16Mode(); |
|
|
|
if ((int)this.method >= 5) |
|
|
|
if (this.method >= WebpEncodingMethod.Level5) |
|
|
|
{ |
|
|
|
// 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.
|
|
|
|
@ -908,7 +908,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy |
|
|
|
if (rdOpt > Vp8RdLevel.RdOptNone) |
|
|
|
{ |
|
|
|
QuantEnc.PickBestIntra16(it, ref rd, this.SegmentInfos, this.Proba); |
|
|
|
if ((int)this.method >= 2) |
|
|
|
if (this.method >= WebpEncodingMethod.Level2) |
|
|
|
{ |
|
|
|
QuantEnc.PickBestIntra4(it, ref rd, this.SegmentInfos, this.Proba, this.maxI4HeaderBits); |
|
|
|
} |
|
|
|
@ -921,7 +921,7 @@ namespace SixLabors.ImageSharp.Formats.Webp.Lossy |
|
|
|
// For method >= 2, pick the best intra4/intra16 based on SSE (~tad slower).
|
|
|
|
// For method <= 1, we don't re-examine the decision but just go ahead with
|
|
|
|
// quantization/reconstruction.
|
|
|
|
QuantEnc.RefineUsingDistortion(it, this.SegmentInfos, rd, (int)this.method >= 2, (int)this.method >= 1, this.MbHeaderLimit); |
|
|
|
QuantEnc.RefineUsingDistortion(it, this.SegmentInfos, rd, this.method >= WebpEncodingMethod.Level2, this.method >= WebpEncodingMethod.Level1, this.MbHeaderLimit); |
|
|
|
} |
|
|
|
|
|
|
|
bool isSkipped = rd.Nz == 0; |
|
|
|
|