Files
sharpcompress/src/SharpCompress/Compressors/LZMA/RangeCoder/RangeCoderBitTree.Async.cs
2026-01-25 15:17:44 +00:00

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;
}
}