Browse Source

Fix in BackwardRefsWithLocalCache: mode was not changed to CacheIdx when there was a color cache hit

pull/1552/head
Brian Popow 6 years ago
parent
commit
abe0271966
  1. 25
      src/ImageSharp/Formats/WebP/Lossless/BackwardReferenceEncoder.cs
  2. 12
      src/ImageSharp/Formats/WebP/Lossless/PixOrCopy.cs

25
src/ImageSharp/Formats/WebP/Lossless/BackwardReferenceEncoder.cs

@ -130,7 +130,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
uint bestBgra; uint bestBgra;
int minPos = (basePosition > windowSize) ? basePosition - windowSize : 0; int minPos = (basePosition > windowSize) ? basePosition - windowSize : 0;
int lengthMax = (maxLen < 256) ? maxLen : 256; int lengthMax = (maxLen < 256) ? maxLen : 256;
pos = (int)chain[basePosition]; pos = chain[basePosition];
int currLength; int currLength;
// Heuristic: use the comparison with the above line as an initialization. // Heuristic: use the comparison with the above line as an initialization.
@ -240,7 +240,6 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
Vp8LBackwardRefs best, Vp8LBackwardRefs best,
Vp8LBackwardRefs worst) Vp8LBackwardRefs worst)
{ {
var histo = new Vp8LHistogram[WebPConstants.MaxColorCacheBits];
int lz77TypeBest = 0; int lz77TypeBest = 0;
double bitCostBest = -1; double bitCostBest = -1;
int cacheBitsInitial = cacheBits; int cacheBitsInitial = cacheBits;
@ -276,8 +275,8 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
} }
// Keep the best backward references. // Keep the best backward references.
histo[0] = new Vp8LHistogram(worst, cacheBitsTmp); var histo = new Vp8LHistogram(worst, cacheBitsTmp);
var bitCost = histo[0].EstimateBits(); var bitCost = histo.EstimateBits();
if (lz77TypeBest == 0 || bitCost < bitCostBest) if (lz77TypeBest == 0 || bitCost < bitCostBest)
{ {
@ -295,8 +294,8 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
{ {
Vp8LHashChain hashChainTmp = (lz77TypeBest == (int)Vp8LLz77Type.Lz77Standard) ? hashChain : hashChainBox; Vp8LHashChain hashChainTmp = (lz77TypeBest == (int)Vp8LLz77Type.Lz77Standard) ? hashChain : hashChainBox;
BackwardReferencesTraceBackwards(width, height, bgra, cacheBits, hashChainTmp, best, worst); BackwardReferencesTraceBackwards(width, height, bgra, cacheBits, hashChainTmp, best, worst);
histo[0] = new Vp8LHistogram(worst, cacheBits); var histo = new Vp8LHistogram(worst, cacheBits);
double bitCostTrace = histo[0].EstimateBits(); double bitCostTrace = histo.EstimateBits();
if (bitCostTrace < bitCostBest) if (bitCostTrace < bitCostBest)
{ {
best = worst; best = worst;
@ -335,7 +334,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
} }
// TODO: Don't use the enumerator here. // TODO: Don't use the enumerator here.
// Find the cache_bits giving the lowest entropy. // Find the cacheBits giving the lowest entropy.
using List<PixOrCopy>.Enumerator c = refs.Refs.GetEnumerator(); using List<PixOrCopy>.Enumerator c = refs.Refs.GetEnumerator();
while (c.MoveNext()) while (c.MoveNext())
{ {
@ -384,11 +383,13 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
uint bgraPrev = bgra[pos] ^ 0xffffffffu; uint bgraPrev = bgra[pos] ^ 0xffffffffu;
// TODO: Original has this loop? // TODO: Original has this loop?
// VP8LPrefixEncode(len, &code, &extra_bits, &extra_bits_value); // int extraBits = 0, extraBitsValue = 0;
// for (i = 0; i <= cache_bits_max; ++i) // int code = LosslessUtils.PrefixEncode(len, ref extraBits, ref extraBitsValue);
// for (int i = 0; i <= cacheBitsMax; ++i)
// { // {
// ++histos[i]->literal_[NUM_LITERAL_CODES + code]; // ++histos[i].Literal[WebPConstants.NumLiteralCodes + code];
// } // }
// Update the color caches. // Update the color caches.
do do
{ {
@ -957,7 +958,9 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
if (ix >= 0) if (ix >= 0)
{ {
// Color cache contains bgraLiteral // Color cache contains bgraLiteral
PixOrCopy.CreateCacheIdx(ix); v.Mode = PixOrCopyMode.CacheIdx;
v.BgraOrDistance = (uint)ix;
v.Len = 1;
} }
else else
{ {

12
src/ImageSharp/Formats/WebP/Lossless/PixOrCopy.cs

@ -16,38 +16,32 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
public static PixOrCopy CreateCacheIdx(int idx) public static PixOrCopy CreateCacheIdx(int idx)
{ {
var retval = new PixOrCopy() return new PixOrCopy()
{ {
Mode = PixOrCopyMode.CacheIdx, Mode = PixOrCopyMode.CacheIdx,
BgraOrDistance = (uint)idx, BgraOrDistance = (uint)idx,
Len = 1 Len = 1
}; };
return retval;
} }
public static PixOrCopy CreateLiteral(uint bgra) public static PixOrCopy CreateLiteral(uint bgra)
{ {
var retval = new PixOrCopy() return new PixOrCopy()
{ {
Mode = PixOrCopyMode.Literal, Mode = PixOrCopyMode.Literal,
BgraOrDistance = bgra, BgraOrDistance = bgra,
Len = 1 Len = 1
}; };
return retval;
} }
public static PixOrCopy CreateCopy(uint distance, ushort len) public static PixOrCopy CreateCopy(uint distance, ushort len)
{ {
var retval = new PixOrCopy() return new PixOrCopy()
{ {
Mode = PixOrCopyMode.Copy, Mode = PixOrCopyMode.Copy,
BgraOrDistance = distance, BgraOrDistance = distance,
Len = len Len = len
}; };
return retval;
} }
public uint Literal(int component) public uint Literal(int component)

Loading…
Cancel
Save