Browse Source

Fix some issues:

- Fix wrong palette code bits init in CalculateBestCacheSize
- Fix wrong slice start index in PrepareMapToPalette
- PixOrCopy: Change len from short to ushort
pull/1552/head
Brian Popow 6 years ago
parent
commit
8538db75e4
  1. 26
      src/ImageSharp/Formats/WebP/Lossless/BackwardReferenceEncoder.cs
  2. 3
      src/ImageSharp/Formats/WebP/Lossless/HuffmanUtils.cs
  3. 6
      src/ImageSharp/Formats/WebP/Lossless/PixOrCopy.cs
  4. 33
      src/ImageSharp/Formats/WebP/Lossless/Vp8LEncoder.cs
  5. 2
      src/ImageSharp/Formats/WebP/Lossless/Vp8LHistogram.cs

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

@ -230,12 +230,10 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
}
/// <summary>
/// Evaluates best possible backward references for specified quality.
/// The input cacheBits to 'GetBackwardReferences' sets the maximum cache
/// bits to use (passing 0 implies disabling the local color cache).
/// Evaluates best possible backward references for specified quality. The input cacheBits to 'GetBackwardReferences'
/// sets the maximum cache bits to use (passing 0 implies disabling the local color cache).
/// The optimal cache bits is evaluated and set for the cacheBits parameter.
/// The return value is the pointer to the best of the two backward refs viz,
/// refs[0] or refs[1].
/// The return value is the pointer to the best of the two backward refs viz, refs[0] or refs[1].
/// </summary>
public static Vp8LBackwardRefs GetBackwardReferences(
int width,
@ -335,9 +333,9 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
int pos = 0;
var colorCache = new ColorCache[WebPConstants.MaxColorCacheBits + 1];
var histos = new Vp8LHistogram[WebPConstants.MaxColorCacheBits + 1];
for (int i = 0; i < WebPConstants.MaxColorCacheBits + 1; i++)
for (int i = 0; i <= WebPConstants.MaxColorCacheBits; i++)
{
histos[i] = new Vp8LHistogram(bestCacheBits);
histos[i] = new Vp8LHistogram(paletteCodeBits: i);
colorCache[i] = new ColorCache();
colorCache[i].Init(i);
}
@ -369,7 +367,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
{
if (colorCache[i].Lookup(key) == pix)
{
++histos[i].Literal[WebPConstants.NumLiteralCodes + WebPConstants.CodeLengthCodes + key];
++histos[i].Literal[WebPConstants.NumLiteralCodes + WebPConstants.NumLengthCodes + key];
}
else
{
@ -563,7 +561,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
if (len != 1)
{
int offset = hashChain.FindOffset(i);
backwardRefs.Add(PixOrCopy.CreateCopy((uint)offset, (short)len));
backwardRefs.Add(PixOrCopy.CreateCopy((uint)offset, (ushort)len));
if (useColorCache)
{
@ -689,7 +687,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
}
else
{
refs.Add(PixOrCopy.CreateCopy((uint)offset, (short)len));
refs.Add(PixOrCopy.CreateCopy((uint)offset, (ushort)len));
if (useColorCache)
{
for (j = i; j < i + len; ++j)
@ -908,7 +906,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
int prevRowLen = (i < xSize) ? 0 : FindMatchLength(bgra.Slice(i), bgra.Slice(i - xSize), 0, maxLen);
if (rleLen >= prevRowLen && rleLen >= MinLength)
{
refs.Add(PixOrCopy.CreateCopy(1, (short)rleLen));
refs.Add(PixOrCopy.CreateCopy(1, (ushort)rleLen));
// We don't need to update the color cache here since it is always the
// same pixel being copied, and that does not change the color cache state.
@ -916,7 +914,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
}
else if (prevRowLen >= MinLength)
{
refs.Add(PixOrCopy.CreateCopy((uint)xSize, (short)prevRowLen));
refs.Add(PixOrCopy.CreateCopy((uint)xSize, (ushort)prevRowLen));
if (useColorCache)
{
for (int k = 0; k < prevRowLen; k++)
@ -936,7 +934,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
if (useColorCache)
{
// TODO: VP8LColorCacheClear();
// TODO: VP8LColorCacheClear()?
}
}
@ -978,7 +976,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
}
}
// TODO: VP8LColorCacheClear(colorCache);
// TODO: VP8LColorCacheClear(colorCache)?
}
private static void BackwardReferences2DLocality(int xSize, Vp8LBackwardRefs refs)

3
src/ImageSharp/Formats/WebP/Lossless/HuffmanUtils.cs

@ -279,13 +279,12 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
{
int value = tree.CodeLengths[i];
int k = i + 1;
int runs;
while (k < depthSize && tree.CodeLengths[k] == value)
{
k++;
}
runs = k - i;
var runs = k - i;
if (value == 0)
{
tokenPos += CodeRepeatedZeros(runs, tokensArray.AsSpan(tokenPos));

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

@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
{
public PixOrCopyMode Mode { get; set; }
public short Len { get; set; }
public ushort Len { get; set; }
public uint BgraOrDistance { get; set; }
@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
return retval;
}
public static PixOrCopy CreateCopy(uint distance, short len)
public static PixOrCopy CreateCopy(uint distance, ushort len)
{
var retval = new PixOrCopy()
{
@ -60,7 +60,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
return this.BgraOrDistance;
}
public short Length()
public ushort Length()
{
return this.Len;
}

33
src/ImageSharp/Formats/WebP/Lossless/Vp8LEncoder.cs

@ -427,7 +427,16 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
foreach (CrunchSubConfig subConfig in config.SubConfigs)
{
Vp8LBackwardRefs refsBest = BackwardReferenceEncoder.GetBackwardReferences(width, height, bgra, quality, subConfig.Lz77, ref cacheBits, hashChain, refsArray[0], refsArray[1]); // TODO : Pass do not cache
Vp8LBackwardRefs refsBest = BackwardReferenceEncoder.GetBackwardReferences(
width,
height,
bgra,
quality,
subConfig.Lz77,
ref cacheBits,
hashChain,
refsArray[0],
refsArray[1]); // TODO : Pass do not cache
// Keep the best references aside and use the other element from the first
// two as a temporary for later usage.
@ -473,13 +482,13 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
this.bitWriter.PutBits((uint)(writeHistogramImage ? 1 : 0), 1);
if (writeHistogramImage)
{
using IMemoryOwner<uint> histogramArgbBuffer = this.memoryAllocator.Allocate<uint>(histogramImageXySize);
Span<uint> histogramArgb = histogramArgbBuffer.GetSpan();
using IMemoryOwner<uint> histogramBgraBuffer = this.memoryAllocator.Allocate<uint>(histogramImageXySize);
Span<uint> histogramBgra = histogramBgraBuffer.GetSpan();
int maxIndex = 0;
for (int i = 0; i < histogramImageXySize; i++)
{
int symbolIndex = histogramSymbols[i] & 0xffff;
histogramArgb[i] = (uint)(symbolIndex << 8);
histogramBgra[i] = (uint)(symbolIndex << 8);
if (symbolIndex >= maxIndex)
{
maxIndex = symbolIndex + 1;
@ -487,7 +496,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
}
this.bitWriter.PutBits((uint)(histogramBits - 2), 3);
this.EncodeImageNoHuffman(histogramArgb, hashChain, refsTmp, refsArray[2], LosslessUtils.SubSampleSize(width, histogramBits), LosslessUtils.SubSampleSize(height, histogramBits), quality);
this.EncodeImageNoHuffman(histogramBgra, hashChain, refsTmp, refsArray[2], LosslessUtils.SubSampleSize(width, histogramBits), LosslessUtils.SubSampleSize(height, histogramBits), quality);
}
// Store Huffman codes.
@ -690,7 +699,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
if (count == 0)
{
// emit minimal tree for empty cases
// Emit minimal tree for empty cases.
// bits: small tree marker: 1, count-1: 0, large 8-bit code: 0, code: 0
this.bitWriter.PutBits(0x01, 4);
}
@ -725,10 +734,12 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
int i;
var codeLengthBitDepth = new byte[WebPConstants.CodeLengthCodes];
var codeLengthBitDepthSymbols = new short[WebPConstants.CodeLengthCodes];
var huffmanCode = new HuffmanTreeCode();
huffmanCode.NumSymbols = WebPConstants.CodeLengthCodes;
huffmanCode.CodeLengths = codeLengthBitDepth;
huffmanCode.Codes = codeLengthBitDepthSymbols;
var huffmanCode = new HuffmanTreeCode
{
NumSymbols = WebPConstants.CodeLengthCodes,
CodeLengths = codeLengthBitDepth,
Codes = codeLengthBitDepthSymbols
};
this.bitWriter.PutBits(0, 1);
var numTokens = HuffmanUtils.CreateCompressedHuffmanTree(tree, tokens);
@ -1313,7 +1324,7 @@ namespace SixLabors.ImageSharp.Formats.WebP.Lossless
/// </summary>
private static void PrepareMapToPalette(Span<uint> palette, int numColors, uint[] sorted, uint[] idxMap)
{
palette.Slice(numColors).CopyTo(sorted);
palette.Slice(0, numColors).CopyTo(sorted);
Array.Sort(sorted, PaletteCompareColorsForSort);
for (int i = 0; i < numColors; i++)
{

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

@ -61,7 +61,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 + ((this.PaletteCodeBits > 0) ? (1 << this.PaletteCodeBits) : 0);
var literalSize = WebPConstants.NumLiteralCodes + WebPConstants.NumLengthCodes + (1 << WebPConstants.MaxColorCacheBits);
this.Literal = new uint[literalSize];
// 5 for literal, red, blue, alpha, distance.

Loading…
Cancel
Save