blob: 061c4edc0196f5b6a4b214590418dbc62d1ef818 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
/* Copyright (C) Teemu Suutari */
#include "RangeDecoder.hpp"
namespace ancient::internal
{
RangeDecoder::BitReader::BitReader()
{
// nothing needed
}
RangeDecoder::BitReader::~BitReader()
{
// nothing needed
}
RangeDecoder::RangeDecoder(BitReader &bitReader,uint16_t initialValue) :
_bitReader(bitReader),
_stream(initialValue)
{
// nothing needed
}
RangeDecoder::~RangeDecoder()
{
// nothing needed
}
uint16_t RangeDecoder::decode(uint16_t length)
{
return ((uint32_t(_stream-_low)+1)*length-1)/(uint32_t(_high-_low)+1);
}
void RangeDecoder::scale(uint16_t newLow,uint16_t newHigh,uint16_t newRange)
{
uint32_t range=uint32_t(_high-_low)+1;
_high=(range*newHigh)/newRange+_low-1;
_low=(range*newLow)/newRange+_low;
auto doubleContext=[&](uint16_t decr)
{
_low-=decr;
_high-=decr;
_stream-=decr;
_low<<=1;
_high=(_high<<1)|1U;
_stream=(_stream<<1)|_bitReader.readBit();
};
for (;;)
{
if (_high<0x8000U)
{
doubleContext(0U);
} else if (_low>=0x8000U) {
doubleContext(0x8000U);
} else if (_low>=0x4000U && _high<0xc000U) {
doubleContext(0x4000U);
} else break;
}
}
}
|