mirror of
https://github.com/adamhathcock/sharpcompress.git
synced 2026-02-11 05:24:56 +00:00
128 lines
3.4 KiB
C#
128 lines
3.4 KiB
C#
#nullable disable
|
|
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace SharpCompress.Compressors.LZMA.RangeCoder;
|
|
|
|
internal readonly partial struct BitTreeEncoder
|
|
{
|
|
public async ValueTask EncodeAsync(
|
|
Encoder rangeEncoder,
|
|
uint symbol,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
uint m = 1;
|
|
for (var bitIndex = _numBitLevels; bitIndex > 0; )
|
|
{
|
|
bitIndex--;
|
|
var bit = (symbol >> bitIndex) & 1;
|
|
await _models[m]
|
|
.EncodeAsync(rangeEncoder, bit, cancellationToken)
|
|
.ConfigureAwait(false);
|
|
m = (m << 1) | bit;
|
|
}
|
|
}
|
|
|
|
public async ValueTask ReverseEncodeAsync(
|
|
Encoder rangeEncoder,
|
|
uint symbol,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
uint m = 1;
|
|
for (uint i = 0; i < _numBitLevels; i++)
|
|
{
|
|
var bit = symbol & 1;
|
|
await _models[m]
|
|
.EncodeAsync(rangeEncoder, bit, cancellationToken)
|
|
.ConfigureAwait(false);
|
|
m = (m << 1) | bit;
|
|
symbol >>= 1;
|
|
}
|
|
}
|
|
|
|
public static async ValueTask ReverseEncodeAsync(
|
|
BitEncoder[] models,
|
|
uint startIndex,
|
|
Encoder rangeEncoder,
|
|
int numBitLevels,
|
|
uint symbol,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
uint m = 1;
|
|
for (var i = 0; i < numBitLevels; i++)
|
|
{
|
|
var bit = symbol & 1;
|
|
await models[startIndex + m]
|
|
.EncodeAsync(rangeEncoder, bit, cancellationToken)
|
|
.ConfigureAwait(false);
|
|
m = (m << 1) | bit;
|
|
symbol >>= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
internal readonly partial struct BitTreeDecoder
|
|
{
|
|
public async ValueTask<uint> DecodeAsync(
|
|
Decoder rangeDecoder,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
uint m = 1;
|
|
for (var bitIndex = _numBitLevels; bitIndex > 0; bitIndex--)
|
|
{
|
|
m =
|
|
(m << 1)
|
|
+ await _models[m]
|
|
.DecodeAsync(rangeDecoder, cancellationToken)
|
|
.ConfigureAwait(false);
|
|
}
|
|
return m - ((uint)1 << _numBitLevels);
|
|
}
|
|
|
|
public async ValueTask<uint> ReverseDecodeAsync(
|
|
Decoder rangeDecoder,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
uint m = 1;
|
|
uint symbol = 0;
|
|
for (var bitIndex = 0; bitIndex < _numBitLevels; bitIndex++)
|
|
{
|
|
var bit = await _models[m]
|
|
.DecodeAsync(rangeDecoder, cancellationToken)
|
|
.ConfigureAwait(false);
|
|
m <<= 1;
|
|
m += bit;
|
|
symbol |= (bit << bitIndex);
|
|
}
|
|
return symbol;
|
|
}
|
|
|
|
public static async ValueTask<uint> ReverseDecodeAsync(
|
|
BitDecoder[] models,
|
|
uint startIndex,
|
|
Decoder rangeDecoder,
|
|
int numBitLevels,
|
|
CancellationToken cancellationToken = default
|
|
)
|
|
{
|
|
uint m = 1;
|
|
uint symbol = 0;
|
|
for (var bitIndex = 0; bitIndex < numBitLevels; bitIndex++)
|
|
{
|
|
var bit = await models[startIndex + m]
|
|
.DecodeAsync(rangeDecoder, cancellationToken)
|
|
.ConfigureAwait(false);
|
|
m <<= 1;
|
|
m += bit;
|
|
symbol |= (bit << bitIndex);
|
|
}
|
|
return symbol;
|
|
}
|
|
}
|