Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
5098 clevermous 1
#include "RangeCoderBitTree.h"
2
#include "lzma.h"
3
 
4
static unsigned _cacheSize;
5
static byte _cache;
6
static uint64 low;
7
static unsigned range;
8
 
9
static unsigned PriceTable[kBitModelTotal >> kNumMoveReducingBits];
10
 
11
void RangeEncoder_Init(void)
12
{
13
	int i;
14
	unsigned start,end,j;
15
	low = 0;
16
	range = 0xFFFFFFFF;
17
	_cacheSize = 1;
18
	_cache = 0;
19
	/* init price table */
20
#define kNumBits (kNumBitModelTotalBits - kNumMoveReducingBits)
21
	for (i=kNumBits;i--;)
22
	{
23
		start = 1 << (kNumBits - i - 1);
24
		end = 1 << (kNumBits - i);
25
		for (j=start;j
26
			PriceTable[j] = (i<
27
			(((end-j)<> (kNumBits - i - 1));
28
	}
29
#undef kNumBits
30
}
31
 
32
void RangeEncoder_ShiftLow(void)
33
{
34
	if ((unsigned)low < 0xFF000000U || (int)(low>>32))
35
	{
36
		byte temp = _cache;
37
		do
38
		{
39
			*curout++ = (byte)(temp + (byte)(low>>32));
40
			temp = 0xFF;
41
		} while (--_cacheSize);
42
		_cache = (byte)((unsigned)low>>24);
43
	}
44
	_cacheSize++;
45
	low = (unsigned)low << 8;
46
}
47
 
48
void RangeEncoder_FlushData(void)
49
{
50
	int i;
51
	for (i=0;i<5;i++)
52
		RangeEncoder_ShiftLow();
53
}
54
 
55
void RangeEncoder_EncodeDirectBits(unsigned value,int numTotalBits)
56
{
57
	int i;
58
	for (i=numTotalBits;i--;)
59
	{
60
		range >>= 1;
61
		if (((value >> i) & 1) == 1)
62
			low += range;
63
		if (range < kTopValue)
64
		{
65
			range <<= 8;
66
			RangeEncoder_ShiftLow();
67
		}
68
	}
69
}
70
 
71
void CMyBitEncoder_Encode(CMyBitEncoder* e,unsigned symbol)
72
{
73
	unsigned newBound;
74
	newBound = (range >> kNumBitModelTotalBits) * *e;
75
	if (symbol == 0)
76
	{
77
		range = newBound;
78
		*e += (kBitModelTotal - *e) >> kNumMoveBits;
79
	}
80
	else
81
	{
82
		low += newBound;
83
		range -= newBound;
84
		*e -= *e >> kNumMoveBits;
85
	}
86
	if (range < kTopValue)
87
	{
88
		range <<= 8;
89
		RangeEncoder_ShiftLow();
90
	}
91
}
92
 
93
unsigned CMyBitEncoder_GetPrice(CMyBitEncoder* e, unsigned symbol)
94
{
95
	return PriceTable[(((*e-symbol)^((-(int)symbol))) & (kBitModelTotal-1)) >> kNumMoveReducingBits];
96
}
97
unsigned CMyBitEncoder_GetPrice0(CMyBitEncoder* e)
98
{
99
	return PriceTable[*e >> kNumMoveReducingBits];
100
}
101
unsigned CMyBitEncoder_GetPrice1(CMyBitEncoder* e)
102
{
103
	return PriceTable[(kBitModelTotal - *e) >> kNumMoveReducingBits];
104
}
105
 
106
void CBitTreeEncoder_Init(NRangeCoder_CBitTreeEncoder*e,int numBitLevels)
107
{
108
	unsigned i;
109
	e->numBitLevels = numBitLevels;
110
	for (i=1;i<((unsigned)1<
111
		CMyBitEncoder_Init(e->Models[i]);
112
}
113
void CBitTreeEncoder_Encode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
114
{
115
	unsigned modelIndex = 1;
116
	int bitIndex;
117
	unsigned bit;
118
	for (bitIndex = e->numBitLevels; bitIndex--;)
119
	{
120
		bit = (symbol >> bitIndex) & 1;
121
		CMyBitEncoder_Encode(&e->Models[modelIndex],bit);
122
		modelIndex = (modelIndex << 1) | bit;
123
	}
124
}
125
void CBitTreeEncoder_ReverseEncode(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
126
{
127
	unsigned modelIndex = 1;
128
	int i;
129
	unsigned bit;
130
	for (i=0;inumBitLevels;i++)
131
	{
132
		bit = symbol & 1;
133
		CMyBitEncoder_Encode(&e->Models[modelIndex],bit);
134
		modelIndex = (modelIndex << 1) | bit;
135
		symbol >>= 1;
136
	}
137
}
138
unsigned CBitTreeEncoder_GetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
139
{
140
	unsigned price = 0;
141
	symbol |= (1 << e->numBitLevels);
142
	while (symbol != 1)
143
	{
144
		price += CMyBitEncoder_GetPrice(&e->Models[symbol>>1],symbol&1);
145
		symbol >>= 1;
146
	}
147
	return price;
148
}
149
unsigned CBitTreeEncoder_ReverseGetPrice(NRangeCoder_CBitTreeEncoder*e,unsigned symbol)
150
{
151
	unsigned price=0;
152
	unsigned modelIndex=1;
153
	int i;
154
	unsigned bit;
155
	for (i=e->numBitLevels;i;i--)
156
	{
157
		bit = symbol&1;
158
		symbol >>= 1;
159
		price += CMyBitEncoder_GetPrice(&e->Models[modelIndex],bit);
160
		modelIndex = (modelIndex<<1)|bit;
161
	}
162
	return price;
163
}
164
unsigned ReverseBitTreeGetPrice(CMyBitEncoder*Models,unsigned NumBitLevels,unsigned symbol)
165
{
166
	unsigned price=0;
167
	unsigned modelIndex=1;
168
	unsigned bit;
169
	int i;
170
	for (i=NumBitLevels;i;i--)
171
	{
172
		bit = symbol & 1;
173
		symbol >>= 1;
174
		price += CMyBitEncoder_GetPrice(Models+modelIndex,bit);
175
		modelIndex = (modelIndex<<1)|bit;
176
	}
177
	return price;
178
}
179
void ReverseBitTreeEncode(CMyBitEncoder*Models,int NumBitLevels,unsigned symbol)
180
{
181
	unsigned modelIndex = 1;
182
	int i;
183
	unsigned bit;
184
	for (i=0;i
185
	{
186
		bit = symbol & 1;
187
		CMyBitEncoder_Encode(Models+modelIndex,bit);
188
		modelIndex = (modelIndex<<1)|bit;
189
		symbol >>= 1;
190
	}
191
}