mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Implementing WebPLossyDecoder.DecodeAlphaData these methods are called from there containing the same code than in the lossless decoder, so we move them to an abstract base class. (not sure if it's a good idea to move the BitReader itself as well, so passing it as a parameter for now)pull/1552/head
3 changed files with 90 additions and 74 deletions
@ -0,0 +1,86 @@ |
|||
// // Copyright (c) Six Labors and contributors.
|
|||
// // Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers; |
|||
|
|||
using SixLabors.ImageSharp.Memory; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.WebP |
|||
{ |
|||
abstract class WebPDecoderBase |
|||
{ |
|||
protected HTreeGroup[] GetHTreeGroupForPos(Vp8LMetadata metadata, int x, int y) |
|||
{ |
|||
uint metaIndex = this.GetMetaIndex(metadata.HuffmanImage, metadata.HuffmanXSize, metadata.HuffmanSubSampleBits, x, y); |
|||
return metadata.HTreeGroups.AsSpan((int)metaIndex).ToArray(); |
|||
} |
|||
|
|||
private uint GetMetaIndex(IMemoryOwner<uint> huffmanImage, int xSize, int bits, int x, int y) |
|||
{ |
|||
if (bits is 0) |
|||
{ |
|||
return 0; |
|||
} |
|||
|
|||
Span<uint> huffmanImageSpan = huffmanImage.GetSpan(); |
|||
return huffmanImageSpan[(xSize * (y >> bits)) + (x >> bits)]; |
|||
} |
|||
|
|||
// TODO: copied from WebPLosslessDecoder
|
|||
protected int GetCopyDistance(int distanceSymbol, Vp8LBitReader bitReader) |
|||
{ |
|||
if (distanceSymbol < 4) |
|||
{ |
|||
return distanceSymbol + 1; |
|||
} |
|||
|
|||
int extraBits = (distanceSymbol - 2) >> 1; |
|||
int offset = (2 + (distanceSymbol & 1)) << extraBits; |
|||
|
|||
return (int)(offset + bitReader.ReadBits(extraBits) + 1); |
|||
} |
|||
|
|||
// TODO: copied from WebPLosslessDecoder
|
|||
protected int GetCopyLength(int lengthSymbol, Vp8LBitReader bitReader) |
|||
{ |
|||
// Length and distance prefixes are encoded the same way.
|
|||
return this.GetCopyDistance(lengthSymbol, bitReader); |
|||
} |
|||
|
|||
// TODO: copied from LosslessDecoder
|
|||
protected static readonly int[] KCodeToPlane = |
|||
{ |
|||
0x18, 0x07, 0x17, 0x19, 0x28, 0x06, 0x27, 0x29, 0x16, 0x1a, |
|||
0x26, 0x2a, 0x38, 0x05, 0x37, 0x39, 0x15, 0x1b, 0x36, 0x3a, |
|||
0x25, 0x2b, 0x48, 0x04, 0x47, 0x49, 0x14, 0x1c, 0x35, 0x3b, |
|||
0x46, 0x4a, 0x24, 0x2c, 0x58, 0x45, 0x4b, 0x34, 0x3c, 0x03, |
|||
0x57, 0x59, 0x13, 0x1d, 0x56, 0x5a, 0x23, 0x2d, 0x44, 0x4c, |
|||
0x55, 0x5b, 0x33, 0x3d, 0x68, 0x02, 0x67, 0x69, 0x12, 0x1e, |
|||
0x66, 0x6a, 0x22, 0x2e, 0x54, 0x5c, 0x43, 0x4d, 0x65, 0x6b, |
|||
0x32, 0x3e, 0x78, 0x01, 0x77, 0x79, 0x53, 0x5d, 0x11, 0x1f, |
|||
0x64, 0x6c, 0x42, 0x4e, 0x76, 0x7a, 0x21, 0x2f, 0x75, 0x7b, |
|||
0x31, 0x3f, 0x63, 0x6d, 0x52, 0x5e, 0x00, 0x74, 0x7c, 0x41, |
|||
0x4f, 0x10, 0x20, 0x62, 0x6e, 0x30, 0x73, 0x7d, 0x51, 0x5f, |
|||
0x40, 0x72, 0x7e, 0x61, 0x6f, 0x50, 0x71, 0x7f, 0x60, 0x70 |
|||
}; |
|||
|
|||
protected static readonly int CodeToPlaneCodes = KCodeToPlane.Length; |
|||
|
|||
protected int PlaneCodeToDistance(int xSize, int planeCode) |
|||
{ |
|||
if (planeCode > CodeToPlaneCodes) |
|||
{ |
|||
return planeCode - CodeToPlaneCodes; |
|||
} |
|||
|
|||
int distCode = KCodeToPlane[planeCode - 1]; |
|||
int yOffset = distCode >> 4; |
|||
int xOffset = 8 - (distCode & 0xf); |
|||
int dist = (yOffset * xSize) + xOffset; |
|||
|
|||
// dist < 1 can happen if xSize is very small.
|
|||
return (dist >= 1) ? dist : 1; |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue