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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
|
/*++
Copyright (c) Alex Ionescu. All rights reserved.
Module Name:
rangedec.c
Abstract:
This module implements the Range Decoder, which is how LZMA describes the
arithmetic coder that it uses to represent the binary representation of the
LZ77 match length-distance pairs after the initial compression pass. At the
implementation level, this coder works with an alphabet of only 2 symbols:
the bit "0", and the bit "1", so there are only ever two probability ranges
that need to be checked each pass. In LZMA, a probability of 100% encodes a
"0", while 0% encodes a "1". Initially, all probabilities are assumed to be
50%. Probabilities are stored using 11-bits (2048 \=\= 100%), and thus use 16
bits of storage. Finally, the range decoder is adaptive, meaning that each
time a bit is decoded, the probabilities are updated: each 0 increases the
probability of another 0, and each 1 decrases it. The algorithm adapts the
probabilities using an exponential moving average with a shift ratio of 5.
Author:
Alex Ionescu (@aionescu) 15-Apr-2020 - Initial version
Environment:
Windows & Linux, user mode and kernel mode.
--*/
#include "minlzlib.h"
//
// The range decoder uses 11 probability bits, where 2048 is 100% chance of a 0
//
#define LZMA_RC_PROBABILITY_BITS 11
#define LZMA_RC_MAX_PROBABILITY (1 << LZMA_RC_PROBABILITY_BITS)
const uint16_t k_LzmaRcHalfProbability = LZMA_RC_MAX_PROBABILITY / 2;
//
// The range decoder uses an exponential moving average of the last probability
// hit (match or miss) with an adaptation rate of 5 bits (which falls in the
// middle of its 11 bits used to encode a probability.
//
#define LZMA_RC_ADAPTATION_RATE_SHIFT 5
//
// The range decoder has enough precision for the range only as long as the top
// 8 bits are still set. Once it falls below, it needs a renormalization step.
//
#define LZMA_RC_MIN_RANGE (1 << 24)
//
// The range decoder must be initialized with 5 bytes, the first of which is
// ignored
//
#define LZMA_RC_INIT_BYTES 5
//
// State used for the binary adaptive arithmetic coder (LZMA Range Decoder)
//
typedef struct _RANGE_DECODER_STATE
{
//
// Start and end location of the current stream's range encoder buffer
//
uint8_t* Start;
uint8_t* Limit;
//
// Current probability range and 32-bit arithmetic encoded sequence code
//
uint32_t Range;
uint32_t Code;
} RANGE_DECODER_STATE, *PRANGE_DECODER_STATE;
RANGE_DECODER_STATE RcState;
bool
RcInitialize (
uint16_t* ChunkSize
)
{
uint8_t i, rcByte;
uint8_t* chunkEnd;
//
// Make sure that the input buffer has enough space for the requirements of
// the range encoder. We (temporarily) seek forward to validate this.
//
if (!BfSeek(*ChunkSize, &chunkEnd))
{
return false;
}
BfSeek(-*ChunkSize, &chunkEnd);
//
// The initial probability range is set to its highest value, after which
// the next 5 bytes are used to initialize the initial code. Note that the
// first byte outputted by the encoder is always going to be zero, so it is
// ignored here.
//
RcState.Range = (uint32_t)-1;
RcState.Code = 0;
for (i = 0; i < LZMA_RC_INIT_BYTES; i++)
{
BfRead(&rcByte);
RcState.Code = (RcState.Code << 8) | rcByte;
}
//
// Store our current location in the buffer now, and how far we can go on
// reading. Then decrease the total chunk size by the count of init bytes,
// so that the caller can check, once done (RcIsComplete), if the code has
// become 0 exactly when the compressed chunk size has been fully consumed
// by the decoder.
//
BfSeek(0, &RcState.Start);
RcState.Limit = RcState.Start + *ChunkSize;
*ChunkSize -= LZMA_RC_INIT_BYTES;
return true;
}
bool
RcCanRead (
void
)
{
uint8_t* pos;
//
// We can keep reading symbols as long as we haven't reached the end of the
// input buffer yet.
//
BfSeek(0, &pos);
return pos <= RcState.Limit;
}
bool
RcIsComplete (
uint32_t* BytesProcessed
)
{
uint8_t* pos;
//
// When the last symbol has been decoded, the last code should be zero as
// there is nothing left to describe. Return the offset in the buffer where
// this occurred (which should be equal to the compressed size).
//
BfSeek(0, &pos);
*BytesProcessed = (uint32_t)(pos - RcState.Start);
return (RcState.Code == 0);
}
void
RcNormalize (
void
)
{
uint8_t rcByte;
//
// Whenever we drop below 24 bits, there is no longer enough precision in
// the probability range not to avoid a "stuck" state where we cannot tell
// apart the two branches (above/below the probability range) because the
// two options appear identical with the number of precision bits that we
// have. In this case, shift the state by a byte (8 bits) and read another.
//
if (RcState.Range < LZMA_RC_MIN_RANGE)
{
RcState.Range <<= 8;
RcState.Code <<= 8;
BfRead(&rcByte);
RcState.Code |= rcByte;
}
}
void
RcAdapt (
bool Miss,
uint16_t* Probability
)
{
//
// In the canonical range encoders out there (including this one used by
// LZMA, we want the probability to adapt (change) as we read more or less
// bits that match our expectation. In order to quickly adapt to change,
// use an exponential moving average. The standard way of doing this is to
// use an integer based adaptation with a shift that's somewhere between
// {1, bits-1}. Since LZMA uses 11 bits for its model, 5 is a nice number
// that lands exactly between 1 and 10.
//
if (Miss)
{
*Probability -= *Probability >> LZMA_RC_ADAPTATION_RATE_SHIFT;
}
else
{
*Probability += (LZMA_RC_MAX_PROBABILITY - *Probability) >>
LZMA_RC_ADAPTATION_RATE_SHIFT;
}
}
uint8_t
RcIsBitSet (
uint16_t* Probability
)
{
uint32_t bound;
uint8_t bit;
//
// Always begin by making sure the range has been normalized for precision
//
RcNormalize();
//
// Check if the current arithmetic code is descried by the next calculated
// proportionally-divided probability range. Recall that the probabilities
// encode the chance of the symbol (bit) being a 0 -- not a 1!
//
// Therefore, if the next chunk of the code lies outside of this new range,
// we are still on the path to our 0. Otherwise, if the code is now part of
// the newly defined range (inclusive), then we produce a 1 and limit the
// range to produce a new range and code for the next decoding pass.
//
bound = (RcState.Range >> LZMA_RC_PROBABILITY_BITS) * *Probability;
if (RcState.Code < bound)
{
RcState.Range = bound;
bit = 0;
}
else
{
RcState.Range -= bound;
RcState.Code -= bound;
bit = 1;
}
//
// Always finish by adapt the probabilities based on the bit value
//
RcAdapt(bit, Probability);
return bit;
}
uint8_t
RcIsFixedBitSet(
void
)
{
uint8_t bit;
//
// This is a specialized version of RcIsBitSet with two differences:
//
// First, there is no adaptive probability -- it is hardcoded to 50%.
//
// Second, because there are 11 bits per probability, and 50% is 1<<10,
// "(LZMA_RC_PROBABILITY_BITS) * Probability" is essentially 1. As such,
// we can just shift by 1 (in other words, halving the range).
//
RcNormalize();
RcState.Range >>= 1;
if (RcState.Code < RcState.Range)
{
bit = 0;
}
else
{
RcState.Code -= RcState.Range;
bit = 1;
}
return bit;
}
uint8_t
RcGetBitTree (
uint16_t* BitModel,
uint16_t Limit
)
{
uint16_t symbol;
//
// Context probability bit trees always begin at index 1. Iterate over each
// decoded bit and just keep shifting it in place, until we reach the total
// expected number of bits, which should never be over 8 (limit is 0x100).
//
// Once decoded, always subtract the limit back from the symbol since we go
// one bit "past" the limit in the loop, as a side effect of the tree being
// off-by-one.
//
for (symbol = 1; symbol < Limit; )
{
symbol = (symbol << 1) | RcIsBitSet(&BitModel[symbol]);
}
return (symbol - Limit) & 0xFF;
}
uint8_t
RcGetReverseBitTree (
uint16_t* BitModel,
uint8_t HighestBit
)
{
uint16_t symbol;
uint8_t i, bit, result;
//
// This is the same logic as in RcGetBitTree, but with the bits actually
// encoded in reverse order. We keep track of the probability index as the
// "symbol" just like RcGetBitTree, but actually decode the result in the
// opposite order.
//
for (i = 0, symbol = 1, result = 0; i < HighestBit; i++)
{
bit = RcIsBitSet(&BitModel[symbol]);
symbol = (symbol << 1) | bit;
result |= bit << i;
}
return result;
}
uint8_t
RcDecodeMatchedBitTree (
uint16_t* BitModel,
uint8_t MatchByte
)
{
uint16_t symbol, bytePos, matchBit;
uint8_t bit;
//
// Parse each bit in the "match byte" (see LzDecodeLiteral), which we call
// a "match bit".
//
// Then, treat this as a special bit tree decoding where two possible trees
// are used: one for when the "match bit" is set, and a separate one for
// when the "match bit" is not set. Since each tree can encode up to 256
// symbols, each one has 0x100 slots.
//
// Finally, we have the original bit tree which we'll revert back to once
// the match bits are no longer in play, which we parse for the remainder
// of the symbol.
//
for (bytePos = MatchByte, symbol = 1; symbol < 0x100; bytePos <<= 1)
{
matchBit = (bytePos >> 7) & 1;
bit = RcIsBitSet(&BitModel[symbol + (0x100 * (matchBit + 1))]);
symbol = (symbol << 1) | bit;
if (matchBit != bit)
{
while (symbol < 0x100)
{
symbol = (symbol << 1) | RcIsBitSet(&BitModel[symbol]);
}
break;
}
}
return symbol & 0xFF;
}
uint32_t
RcGetFixed (
uint8_t HighestBit
)
{
uint32_t symbol;
//
// Fixed probability bit trees always begin at index 0. Iterate over each
// decoded bit and just keep shifting it in place, until we reach the total
// expected number of bits (typically never higher than 26 -- the maximum
// number of "direct bits" that the distance of a "match" can encode).
//
symbol = 0;
do
{
symbol = (symbol << 1) | RcIsFixedBitSet();
} while (--HighestBit > 0);
return symbol;
}
void
RcSetDefaultProbability (
uint16_t* Probability
)
{
//
// By default, we initialize the probabilities to 0.5 (50% chance).
//
*Probability = k_LzmaRcHalfProbability;
}
|