Path: blob/master/deps/LZMA-SDK/DOC/lzma-specification.txt
9416 views
LZMA specification (DRAFT version)1----------------------------------23Author: Igor Pavlov4Date: 2015-06-1456This specification defines the format of LZMA compressed data and lzma file format.78Notation9--------1011We use the syntax of C++ programming language.12We use the following types in C++ code:13unsigned - unsigned integer, at least 16 bits in size14int - signed integer, at least 16 bits in size15UInt64 - 64-bit unsigned integer16UInt32 - 32-bit unsigned integer17UInt16 - 16-bit unsigned integer18Byte - 8-bit unsigned integer19bool - boolean type with two possible values: false, true202122lzma file format23================2425The lzma file contains the raw LZMA stream and the header with related properties.2627The files in that format use ".lzma" extension.2829The lzma file format layout:3031Offset Size Description32330 1 LZMA model properties (lc, lp, pb) in encoded form341 4 Dictionary size (32-bit unsigned integer, little-endian)355 8 Uncompressed size (64-bit unsigned integer, little-endian)3613 Compressed data (LZMA stream)3738LZMA properties:3940name Range Description4142lc [0, 8] the number of "literal context" bits43lp [0, 4] the number of "literal pos" bits44pb [0, 4] the number of "pos" bits45dictSize [0, 2^32 - 1] the dictionary size4647The following code encodes LZMA properties:4849void EncodeProperties(Byte *properties)50{51properties[0] = (Byte)((pb * 5 + lp) * 9 + lc);52Set_UInt32_LittleEndian(properties + 1, dictSize);53}5455If the value of dictionary size in properties is smaller than (1 << 12),56the LZMA decoder must set the dictionary size variable to (1 << 12).5758#define LZMA_DIC_MIN (1 << 12)5960unsigned lc, pb, lp;61UInt32 dictSize;62UInt32 dictSizeInProperties;6364void DecodeProperties(const Byte *properties)65{66unsigned d = properties[0];67if (d >= (9 * 5 * 5))68throw "Incorrect LZMA properties";69lc = d % 9;70d /= 9;71pb = d / 5;72lp = d % 5;73dictSizeInProperties = 0;74for (int i = 0; i < 4; i++)75dictSizeInProperties |= (UInt32)properties[i + 1] << (8 * i);76dictSize = dictSizeInProperties;77if (dictSize < LZMA_DIC_MIN)78dictSize = LZMA_DIC_MIN;79}8081If "Uncompressed size" field contains ones in all 64 bits, it means that82uncompressed size is unknown and there is the "end marker" in stream,83that indicates the end of decoding point.84In opposite case, if the value from "Uncompressed size" field is not85equal to ((2^64) - 1), the LZMA stream decoding must be finished after86specified number of bytes (Uncompressed size) is decoded. And if there87is the "end marker", the LZMA decoder must read that marker also.888990The new scheme to encode LZMA properties91----------------------------------------9293If LZMA compression is used for some another format, it's recommended to94use a new improved scheme to encode LZMA properties. That new scheme was95used in xz format that uses the LZMA2 compression algorithm.96The LZMA2 is a new compression algorithm that is based on the LZMA algorithm.9798The dictionary size in LZMA2 is encoded with just one byte and LZMA2 supports99only reduced set of dictionary sizes:100(2 << 11), (3 << 11),101(2 << 12), (3 << 12),102...103(2 << 30), (3 << 30),104(2 << 31) - 1105106The dictionary size can be extracted from encoded value with the following code:107108dictSize = (p == 40) ? 0xFFFFFFFF : (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11));109110Also there is additional limitation (lc + lp <= 4) in LZMA2 for values of111"lc" and "lp" properties:112113if (lc + lp > 4)114throw "Unsupported properties: (lc + lp) > 4";115116There are some advantages for LZMA decoder with such (lc + lp) value117limitation. It reduces the maximum size of tables allocated by decoder.118And it reduces the complexity of initialization procedure, that can be119important to keep high speed of decoding of big number of small LZMA streams.120121It's recommended to use that limitation (lc + lp <= 4) for any new format122that uses LZMA compression. Note that the combinations of "lc" and "lp"123parameters, where (lc + lp > 4), can provide significant improvement in124compression ratio only in some rare cases.125126The LZMA properties can be encoded into two bytes in new scheme:127128Offset Size Description1291300 1 The dictionary size encoded with LZMA2 scheme1311 1 LZMA model properties (lc, lp, pb) in encoded form132133134The RAM usage135=============136137The RAM usage for LZMA decoder is determined by the following parts:1381391) The Sliding Window (from 4 KiB to 4 GiB).1402) The probability model counter arrays (arrays of 16-bit variables).1413) Some additional state variables (about 10 variables of 32-bit integers).142143144The RAM usage for Sliding Window145--------------------------------146147There are two main scenarios of decoding:1481491) The decoding of full stream to one RAM buffer.150151If we decode full LZMA stream to one output buffer in RAM, the decoder152can use that output buffer as sliding window. So the decoder doesn't153need additional buffer allocated for sliding window.1541552) The decoding to some external storage.156157If we decode LZMA stream to external storage, the decoder must allocate158the buffer for sliding window. The size of that buffer must be equal159or larger than the value of dictionary size from properties of LZMA stream.160161In this specification we describe the code for decoding to some external162storage. The optimized version of code for decoding of full stream to one163output RAM buffer can require some minor changes in code.164165166The RAM usage for the probability model counters167------------------------------------------------168169The size of the probability model counter arrays is calculated with the170following formula:171172size_of_prob_arrays = 1846 + 768 * (1 << (lp + lc))173174Each probability model counter is 11-bit unsigned integer.175If we use 16-bit integer variables (2-byte integers) for these probability176model counters, the RAM usage required by probability model counter arrays177can be estimated with the following formula:178179RAM = 4 KiB + 1.5 KiB * (1 << (lp + lc))180181For example, for default LZMA parameters (lp = 0 and lc = 3), the RAM usage is182183RAM_lc3_lp0 = 4 KiB + 1.5 KiB * 8 = 16 KiB184185The maximum RAM state usage is required for decoding the stream with lp = 4186and lc = 8:187188RAM_lc8_lp4 = 4 KiB + 1.5 KiB * 4096 = 6148 KiB189190If the decoder uses LZMA2's limited property condition191(lc + lp <= 4), the RAM usage will be not larger than192193RAM_lc_lp_4 = 4 KiB + 1.5 KiB * 16 = 28 KiB194195196The RAM usage for encoder197-------------------------198199There are many variants for LZMA encoding code.200These variants have different values for memory consumption.201Note that memory consumption for LZMA Encoder can not be202smaller than memory consumption of LZMA Decoder for same stream.203204The RAM usage required by modern effective implementation of205LZMA Encoder can be estimated with the following formula:206207Encoder_RAM_Usage = 4 MiB + 11 * dictionarySize.208209But there are some modes of the encoder that require less memory.210211212LZMA Decoding213=============214215The LZMA compression algorithm uses LZ-based compression with Sliding Window216and Range Encoding as entropy coding method.217218219Sliding Window220--------------221222LZMA uses Sliding Window compression similar to LZ77 algorithm.223224LZMA stream must be decoded to the sequence that consists225of MATCHES and LITERALS:226227- a LITERAL is a 8-bit character (one byte).228The decoder just puts that LITERAL to the uncompressed stream.229230- a MATCH is a pair of two numbers (DISTANCE-LENGTH pair).231The decoder takes one byte exactly "DISTANCE" characters behind232current position in the uncompressed stream and puts it to233uncompressed stream. The decoder must repeat it "LENGTH" times.234235The "DISTANCE" can not be larger than dictionary size.236And the "DISTANCE" can not be larger than the number of bytes in237the uncompressed stream that were decoded before that match.238239In this specification we use cyclic buffer to implement Sliding Window240for LZMA decoder:241242class COutWindow243{244Byte *Buf;245UInt32 Pos;246UInt32 Size;247bool IsFull;248249public:250unsigned TotalPos;251COutStream OutStream;252253COutWindow(): Buf(NULL) {}254~COutWindow() { delete []Buf; }255256void Create(UInt32 dictSize)257{258Buf = new Byte[dictSize];259Pos = 0;260Size = dictSize;261IsFull = false;262TotalPos = 0;263}264265void PutByte(Byte b)266{267TotalPos++;268Buf[Pos++] = b;269if (Pos == Size)270{271Pos = 0;272IsFull = true;273}274OutStream.WriteByte(b);275}276277Byte GetByte(UInt32 dist) const278{279return Buf[dist <= Pos ? Pos - dist : Size - dist + Pos];280}281282void CopyMatch(UInt32 dist, unsigned len)283{284for (; len > 0; len--)285PutByte(GetByte(dist));286}287288bool CheckDistance(UInt32 dist) const289{290return dist <= Pos || IsFull;291}292293bool IsEmpty() const294{295return Pos == 0 && !IsFull;296}297};298299300In another implementation it's possible to use one buffer that contains301Sliding Window and the whole data stream after uncompressing.302303304Range Decoder305-------------306307LZMA algorithm uses Range Encoding (1) as entropy coding method.308309LZMA stream contains just one very big number in big-endian encoding.310LZMA decoder uses the Range Decoder to extract a sequence of binary311symbols from that big number.312313The state of the Range Decoder:314315struct CRangeDecoder316{317UInt32 Range;318UInt32 Code;319InputStream *InStream;320321bool Corrupted;322}323324The notes about UInt32 type for the "Range" and "Code" variables:325326It's possible to use 64-bit (unsigned or signed) integer type327for the "Range" and the "Code" variables instead of 32-bit unsigned,328but some additional code must be used to truncate the values to329low 32-bits after some operations.330331If the programming language does not support 32-bit unsigned integer type332(like in case of JAVA language), it's possible to use 32-bit signed integer,333but some code must be changed. For example, it's required to change the code334that uses comparison operations for UInt32 variables in this specification.335336The Range Decoder can be in some states that can be treated as337"Corruption" in LZMA stream. The Range Decoder uses the variable "Corrupted":338339(Corrupted == false), if the Range Decoder has not detected any corruption.340(Corrupted == true), if the Range Decoder has detected some corruption.341342The reference LZMA Decoder ignores the value of the "Corrupted" variable.343So it continues to decode the stream, even if the corruption can be detected344in the Range Decoder. To provide the full compatibility with output of the345reference LZMA Decoder, another LZMA Decoder implementations must also346ignore the value of the "Corrupted" variable.347348The LZMA Encoder is required to create only such LZMA streams, that will not349lead the Range Decoder to states, where the "Corrupted" variable is set to true.350351The Range Decoder reads first 5 bytes from input stream to initialize352the state:353354bool CRangeDecoder::Init()355{356Corrupted = false;357Range = 0xFFFFFFFF;358Code = 0;359360Byte b = InStream->ReadByte();361362for (int i = 0; i < 4; i++)363Code = (Code << 8) | InStream->ReadByte();364365if (b != 0 || Code == Range)366Corrupted = true;367return b == 0;368}369370The LZMA Encoder always writes ZERO in initial byte of compressed stream.371That scheme allows to simplify the code of the Range Encoder in the372LZMA Encoder. If initial byte is not equal to ZERO, the LZMA Decoder must373stop decoding and report error.374375After the last bit of data was decoded by Range Decoder, the value of the376"Code" variable must be equal to 0. The LZMA Decoder must check it by377calling the IsFinishedOK() function:378379bool IsFinishedOK() const { return Code == 0; }380381If there is corruption in data stream, there is big probability that382the "Code" value will be not equal to 0 in the Finish() function. So that383check in the IsFinishedOK() function provides very good feature for384corruption detection.385386The value of the "Range" variable before each bit decoding can not be smaller387than ((UInt32)1 << 24). The Normalize() function keeps the "Range" value in388described range.389390#define kTopValue ((UInt32)1 << 24)391392void CRangeDecoder::Normalize()393{394if (Range < kTopValue)395{396Range <<= 8;397Code = (Code << 8) | InStream->ReadByte();398}399}400401Notes: if the size of the "Code" variable is larger than 32 bits, it's402required to keep only low 32 bits of the "Code" variable after the change403in Normalize() function.404405If the LZMA Stream is not corrupted, the value of the "Code" variable is406always smaller than value of the "Range" variable.407But the Range Decoder ignores some types of corruptions, so the value of408the "Code" variable can be equal or larger than value of the "Range" variable409for some "Corrupted" archives.410411412LZMA uses Range Encoding only with binary symbols of two types:4131) binary symbols with fixed and equal probabilities (direct bits)4142) binary symbols with predicted probabilities415416The DecodeDirectBits() function decodes the sequence of direct bits:417418UInt32 CRangeDecoder::DecodeDirectBits(unsigned numBits)419{420UInt32 res = 0;421do422{423Range >>= 1;424Code -= Range;425UInt32 t = 0 - ((UInt32)Code >> 31);426Code += Range & t;427428if (Code == Range)429Corrupted = true;430431Normalize();432res <<= 1;433res += t + 1;434}435while (--numBits);436return res;437}438439440The Bit Decoding with Probability Model441---------------------------------------442443The task of Bit Probability Model is to estimate probabilities of binary444symbols. And then it provides the Range Decoder with that information.445The better prediction provides better compression ratio.446The Bit Probability Model uses statistical data of previous decoded447symbols.448449That estimated probability is presented as 11-bit unsigned integer value450that represents the probability of symbol "0".451452#define kNumBitModelTotalBits 11453454Mathematical probabilities can be presented with the following formulas:455probability(symbol_0) = prob / 2048.456probability(symbol_1) = 1 - Probability(symbol_0) =457= 1 - prob / 2048 =458= (2048 - prob) / 2048459where the "prob" variable contains 11-bit integer probability counter.460461It's recommended to use 16-bit unsigned integer type, to store these 11-bit462probability values:463464typedef UInt16 CProb;465466Each probability value must be initialized with value ((1 << 11) / 2),467that represents the state, where probabilities of symbols 0 and 1468are equal to 0.5:469470#define PROB_INIT_VAL ((1 << kNumBitModelTotalBits) / 2)471472The INIT_PROBS macro is used to initialize the array of CProb variables:473474#define INIT_PROBS(p) \475{ for (unsigned i = 0; i < sizeof(p) / sizeof(p[0]); i++) p[i] = PROB_INIT_VAL; }476477478The DecodeBit() function decodes one bit.479The LZMA decoder provides the pointer to CProb variable that contains480information about estimated probability for symbol 0 and the Range Decoder481updates that CProb variable after decoding. The Range Decoder increases482estimated probability of the symbol that was decoded:483484#define kNumMoveBits 5485486unsigned CRangeDecoder::DecodeBit(CProb *prob)487{488unsigned v = *prob;489UInt32 bound = (Range >> kNumBitModelTotalBits) * v;490unsigned symbol;491if (Code < bound)492{493v += ((1 << kNumBitModelTotalBits) - v) >> kNumMoveBits;494Range = bound;495symbol = 0;496}497else498{499v -= v >> kNumMoveBits;500Code -= bound;501Range -= bound;502symbol = 1;503}504*prob = (CProb)v;505Normalize();506return symbol;507}508509510The Binary Tree of bit model counters511-------------------------------------512513LZMA uses a tree of Bit model variables to decode symbol that needs514several bits for storing. There are two versions of such trees in LZMA:5151) the tree that decodes bits from high bit to low bit (the normal scheme).5162) the tree that decodes bits from low bit to high bit (the reverse scheme).517518Each binary tree structure supports different size of decoded symbol519(the size of binary sequence that contains value of symbol).520If that size of decoded symbol is "NumBits" bits, the tree structure521uses the array of (2 << NumBits) counters of CProb type.522But only ((2 << NumBits) - 1) items are used by encoder and decoder.523The first item (the item with index equal to 0) in array is unused.524That scheme with unused array's item allows to simplify the code.525526unsigned BitTreeReverseDecode(CProb *probs, unsigned numBits, CRangeDecoder *rc)527{528unsigned m = 1;529unsigned symbol = 0;530for (unsigned i = 0; i < numBits; i++)531{532unsigned bit = rc->DecodeBit(&probs[m]);533m <<= 1;534m += bit;535symbol |= (bit << i);536}537return symbol;538}539540template <unsigned NumBits>541class CBitTreeDecoder542{543CProb Probs[(unsigned)1 << NumBits];544545public:546547void Init()548{549INIT_PROBS(Probs);550}551552unsigned Decode(CRangeDecoder *rc)553{554unsigned m = 1;555for (unsigned i = 0; i < NumBits; i++)556m = (m << 1) + rc->DecodeBit(&Probs[m]);557return m - ((unsigned)1 << NumBits);558}559560unsigned ReverseDecode(CRangeDecoder *rc)561{562return BitTreeReverseDecode(Probs, NumBits, rc);563}564};565566567LZ part of LZMA568---------------569570LZ part of LZMA describes details about the decoding of MATCHES and LITERALS.571572573The Literal Decoding574--------------------575576The LZMA Decoder uses (1 << (lc + lp)) tables with CProb values, where577each table contains 0x300 CProb values:578579CProb *LitProbs;580581void CreateLiterals()582{583LitProbs = new CProb[(UInt32)0x300 << (lc + lp)];584}585586void InitLiterals()587{588UInt32 num = (UInt32)0x300 << (lc + lp);589for (UInt32 i = 0; i < num; i++)590LitProbs[i] = PROB_INIT_VAL;591}592593To select the table for decoding it uses the context that consists of594(lc) high bits from previous literal and (lp) low bits from value that595represents current position in outputStream.596597If (State > 7), the Literal Decoder also uses "matchByte" that represents598the byte in OutputStream at position the is the DISTANCE bytes before599current position, where the DISTANCE is the distance in DISTANCE-LENGTH pair600of latest decoded match.601602The following code decodes one literal and puts it to Sliding Window buffer:603604void DecodeLiteral(unsigned state, UInt32 rep0)605{606unsigned prevByte = 0;607if (!OutWindow.IsEmpty())608prevByte = OutWindow.GetByte(1);609610unsigned symbol = 1;611unsigned litState = ((OutWindow.TotalPos & ((1 << lp) - 1)) << lc) + (prevByte >> (8 - lc));612CProb *probs = &LitProbs[(UInt32)0x300 * litState];613614if (state >= 7)615{616unsigned matchByte = OutWindow.GetByte(rep0 + 1);617do618{619unsigned matchBit = (matchByte >> 7) & 1;620matchByte <<= 1;621unsigned bit = RangeDec.DecodeBit(&probs[((1 + matchBit) << 8) + symbol]);622symbol = (symbol << 1) | bit;623if (matchBit != bit)624break;625}626while (symbol < 0x100);627}628while (symbol < 0x100)629symbol = (symbol << 1) | RangeDec.DecodeBit(&probs[symbol]);630OutWindow.PutByte((Byte)(symbol - 0x100));631}632633634The match length decoding635-------------------------636637The match length decoder returns normalized (zero-based value)638length of match. That value can be converted to real length of the match639with the following code:640641#define kMatchMinLen 2642643matchLen = len + kMatchMinLen;644645The match length decoder can return the values from 0 to 271.646And the corresponded real match length values can be in the range647from 2 to 273.648649The following scheme is used for the match length encoding:650651Binary encoding Binary Tree structure Zero-based match length652sequence (binary + decimal):6536540 xxx LowCoder[posState] xxx6551 0 yyy MidCoder[posState] yyy + 86561 1 zzzzzzzz HighCoder zzzzzzzz + 16657658LZMA uses bit model variable "Choice" to decode the first selection bit.659660If the first selection bit is equal to 0, the decoder uses binary tree661LowCoder[posState] to decode 3-bit zero-based match length (xxx).662663If the first selection bit is equal to 1, the decoder uses bit model664variable "Choice2" to decode the second selection bit.665666If the second selection bit is equal to 0, the decoder uses binary tree667MidCoder[posState] to decode 3-bit "yyy" value, and zero-based match668length is equal to (yyy + 8).669670If the second selection bit is equal to 1, the decoder uses binary tree671HighCoder to decode 8-bit "zzzzzzzz" value, and zero-based672match length is equal to (zzzzzzzz + 16).673674LZMA uses "posState" value as context to select the binary tree675from LowCoder and MidCoder binary tree arrays:676677unsigned posState = OutWindow.TotalPos & ((1 << pb) - 1);678679The full code of the length decoder:680681class CLenDecoder682{683CProb Choice;684CProb Choice2;685CBitTreeDecoder<3> LowCoder[1 << kNumPosBitsMax];686CBitTreeDecoder<3> MidCoder[1 << kNumPosBitsMax];687CBitTreeDecoder<8> HighCoder;688689public:690691void Init()692{693Choice = PROB_INIT_VAL;694Choice2 = PROB_INIT_VAL;695HighCoder.Init();696for (unsigned i = 0; i < (1 << kNumPosBitsMax); i++)697{698LowCoder[i].Init();699MidCoder[i].Init();700}701}702703unsigned Decode(CRangeDecoder *rc, unsigned posState)704{705if (rc->DecodeBit(&Choice) == 0)706return LowCoder[posState].Decode(rc);707if (rc->DecodeBit(&Choice2) == 0)708return 8 + MidCoder[posState].Decode(rc);709return 16 + HighCoder.Decode(rc);710}711};712713The LZMA decoder uses two instances of CLenDecoder class.714The first instance is for the matches of "Simple Match" type,715and the second instance is for the matches of "Rep Match" type:716717CLenDecoder LenDecoder;718CLenDecoder RepLenDecoder;719720721The match distance decoding722---------------------------723724LZMA supports dictionary sizes up to 4 GiB minus 1.725The value of match distance (decoded by distance decoder) can be726from 1 to 2^32. But the distance value that is equal to 2^32 is used to727indicate the "End of stream" marker. So real largest match distance728that is used for LZ-window match is (2^32 - 1).729730LZMA uses normalized match length (zero-based length)731to calculate the context state "lenState" do decode the distance value:732733#define kNumLenToPosStates 4734735unsigned lenState = len;736if (lenState > kNumLenToPosStates - 1)737lenState = kNumLenToPosStates - 1;738739The distance decoder returns the "dist" value that is zero-based value740of match distance. The real match distance can be calculated with the741following code:742743matchDistance = dist + 1;744745The state of the distance decoder and the initialization code:746747#define kEndPosModelIndex 14748#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))749#define kNumAlignBits 4750751CBitTreeDecoder<6> PosSlotDecoder[kNumLenToPosStates];752CProb PosDecoders[1 + kNumFullDistances - kEndPosModelIndex];753CBitTreeDecoder<kNumAlignBits> AlignDecoder;754755void InitDist()756{757for (unsigned i = 0; i < kNumLenToPosStates; i++)758PosSlotDecoder[i].Init();759AlignDecoder.Init();760INIT_PROBS(PosDecoders);761}762763At first stage the distance decoder decodes 6-bit "posSlot" value with bit764tree decoder from PosSlotDecoder array. It's possible to get 2^6=64 different765"posSlot" values.766767unsigned posSlot = PosSlotDecoder[lenState].Decode(&RangeDec);768769The encoding scheme for distance value is shown in the following table:770771posSlot (decimal) /772zero-based distance (binary)7730 07741 17752 107763 117777784 10 x7795 11 x7806 10 xx7817 11 xx7828 10 xxx7839 11 xxx78410 10 xxxx78511 11 xxxx78612 10 xxxxx78713 11 xxxxx78878914 10 yy zzzz79015 11 yy zzzz79116 10 yyy zzzz79217 11 yyy zzzz793...79462 10 yyyyyyyyyyyyyyyyyyyyyyyyyy zzzz79563 11 yyyyyyyyyyyyyyyyyyyyyyyyyy zzzz796797where798"x ... x" means the sequence of binary symbols encoded with binary tree and799"Reverse" scheme. It uses separated binary tree for each posSlot from 4 to 13.800"y" means direct bit encoded with range coder.801"zzzz" means the sequence of four binary symbols encoded with binary802tree with "Reverse" scheme, where one common binary tree "AlignDecoder"803is used for all posSlot values.804805If (posSlot < 4), the "dist" value is equal to posSlot value.806807If (posSlot >= 4), the decoder uses "posSlot" value to calculate the value of808the high bits of "dist" value and the number of the low bits.809810If (4 <= posSlot < kEndPosModelIndex), the decoder uses bit tree decoders.811(one separated bit tree decoder per one posSlot value) and "Reverse" scheme.812In this implementation we use one CProb array "PosDecoders" that contains813all CProb variables for all these bit decoders.814815if (posSlot >= kEndPosModelIndex), the middle bits are decoded as direct816bits from RangeDecoder and the low 4 bits are decoded with a bit tree817decoder "AlignDecoder" with "Reverse" scheme.818819The code to decode zero-based match distance:820821unsigned DecodeDistance(unsigned len)822{823unsigned lenState = len;824if (lenState > kNumLenToPosStates - 1)825lenState = kNumLenToPosStates - 1;826827unsigned posSlot = PosSlotDecoder[lenState].Decode(&RangeDec);828if (posSlot < 4)829return posSlot;830831unsigned numDirectBits = (unsigned)((posSlot >> 1) - 1);832UInt32 dist = ((2 | (posSlot & 1)) << numDirectBits);833if (posSlot < kEndPosModelIndex)834dist += BitTreeReverseDecode(PosDecoders + dist - posSlot, numDirectBits, &RangeDec);835else836{837dist += RangeDec.DecodeDirectBits(numDirectBits - kNumAlignBits) << kNumAlignBits;838dist += AlignDecoder.ReverseDecode(&RangeDec);839}840return dist;841}842843844845LZMA Decoding modes846-------------------847848There are 2 types of LZMA streams:8498501) The stream with "End of stream" marker.8512) The stream without "End of stream" marker.852853And the LZMA Decoder supports 3 modes of decoding:8548551) The unpack size is undefined. The LZMA decoder stops decoding after856getting "End of stream" marker.857The input variables for that case:858859markerIsMandatory = true860unpackSizeDefined = false861unpackSize contains any value8628632) The unpack size is defined and LZMA decoder supports both variants,864where the stream can contain "End of stream" marker or the stream is865finished without "End of stream" marker. The LZMA decoder must detect866any of these situations.867The input variables for that case:868869markerIsMandatory = false870unpackSizeDefined = true871unpackSize contains unpack size8728733) The unpack size is defined and the LZMA stream must contain874"End of stream" marker875The input variables for that case:876877markerIsMandatory = true878unpackSizeDefined = true879unpackSize contains unpack size880881882The main loop of decoder883------------------------884885The main loop of LZMA decoder:886887Initialize the LZMA state.888loop889{890// begin of loop891Check "end of stream" conditions.892Decode Type of MATCH / LITERAL.893If it's LITERAL, decode LITERAL value and put the LITERAL to Window.894If it's MATCH, decode the length of match and the match distance.895Check error conditions, check end of stream conditions and copy896the sequence of match bytes from sliding window to current position897in window.898Go to begin of loop899}900901The reference implementation of LZMA decoder uses "unpackSize" variable902to keep the number of remaining bytes in output stream. So it reduces903"unpackSize" value after each decoded LITERAL or MATCH.904905The following code contains the "end of stream" condition check at the start906of the loop:907908if (unpackSizeDefined && unpackSize == 0 && !markerIsMandatory)909if (RangeDec.IsFinishedOK())910return LZMA_RES_FINISHED_WITHOUT_MARKER;911912LZMA uses three types of matches:9139141) "Simple Match" - the match with distance value encoded with bit models.9159162) "Rep Match" - the match that uses the distance from distance917history table.9189193) "Short Rep Match" - the match of single byte length, that uses the latest920distance from distance history table.921922The LZMA decoder keeps the history of latest 4 match distances that were used923by decoder. That set of 4 variables contains zero-based match distances and924these variables are initialized with zero values:925926UInt32 rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;927928The LZMA decoder uses binary model variables to select type of MATCH or LITERAL:929930#define kNumStates 12931#define kNumPosBitsMax 4932933CProb IsMatch[kNumStates << kNumPosBitsMax];934CProb IsRep[kNumStates];935CProb IsRepG0[kNumStates];936CProb IsRepG1[kNumStates];937CProb IsRepG2[kNumStates];938CProb IsRep0Long[kNumStates << kNumPosBitsMax];939940The decoder uses "state" variable value to select exact variable941from "IsRep", "IsRepG0", "IsRepG1" and "IsRepG2" arrays.942The "state" variable can get the value from 0 to 11.943Initial value for "state" variable is zero:944945unsigned state = 0;946947The "state" variable is updated after each LITERAL or MATCH with one of the948following functions:949950unsigned UpdateState_Literal(unsigned state)951{952if (state < 4) return 0;953else if (state < 10) return state - 3;954else return state - 6;955}956unsigned UpdateState_Match (unsigned state) { return state < 7 ? 7 : 10; }957unsigned UpdateState_Rep (unsigned state) { return state < 7 ? 8 : 11; }958unsigned UpdateState_ShortRep(unsigned state) { return state < 7 ? 9 : 11; }959960The decoder calculates "state2" variable value to select exact variable from961"IsMatch" and "IsRep0Long" arrays:962963unsigned posState = OutWindow.TotalPos & ((1 << pb) - 1);964unsigned state2 = (state << kNumPosBitsMax) + posState;965966The decoder uses the following code flow scheme to select exact967type of LITERAL or MATCH:968969IsMatch[state2] decode9700 - the Literal9711 - the Match972IsRep[state] decode9730 - Simple Match9741 - Rep Match975IsRepG0[state] decode9760 - the distance is rep0977IsRep0Long[state2] decode9780 - Short Rep Match9791 - Rep Match 09801 -981IsRepG1[state] decode9820 - Rep Match 19831 -984IsRepG2[state] decode9850 - Rep Match 29861 - Rep Match 3987988989LITERAL symbol990--------------991If the value "0" was decoded with IsMatch[state2] decoding, we have "LITERAL" type.992993At first the LZMA decoder must check that it doesn't exceed994specified uncompressed size:995996if (unpackSizeDefined && unpackSize == 0)997return LZMA_RES_ERROR;998999Then it decodes literal value and puts it to sliding window:10001001DecodeLiteral(state, rep0);10021003Then the decoder must update the "state" value and "unpackSize" value;10041005state = UpdateState_Literal(state);1006unpackSize--;10071008Then the decoder must go to the begin of main loop to decode next Match or Literal.100910101011Simple Match1012------------10131014If the value "1" was decoded with IsMatch[state2] decoding,1015we have the "Simple Match" type.10161017The distance history table is updated with the following scheme:10181019rep3 = rep2;1020rep2 = rep1;1021rep1 = rep0;10221023The zero-based length is decoded with "LenDecoder":10241025len = LenDecoder.Decode(&RangeDec, posState);10261027The state is update with UpdateState_Match function:10281029state = UpdateState_Match(state);10301031and the new "rep0" value is decoded with DecodeDistance:10321033rep0 = DecodeDistance(len);10341035That "rep0" will be used as zero-based distance for current match.10361037If the value of "rep0" is equal to 0xFFFFFFFF, it means that we have1038"End of stream" marker, so we can stop decoding and check finishing1039condition in Range Decoder:10401041if (rep0 == 0xFFFFFFFF)1042return RangeDec.IsFinishedOK() ?1043LZMA_RES_FINISHED_WITH_MARKER :1044LZMA_RES_ERROR;10451046If uncompressed size is defined, LZMA decoder must check that it doesn't1047exceed that specified uncompressed size:10481049if (unpackSizeDefined && unpackSize == 0)1050return LZMA_RES_ERROR;10511052Also the decoder must check that "rep0" value is not larger than dictionary size1053and is not larger than the number of already decoded bytes:10541055if (rep0 >= dictSize || !OutWindow.CheckDistance(rep0))1056return LZMA_RES_ERROR;10571058Then the decoder must copy match bytes as described in1059"The match symbols copying" section.106010611062Rep Match1063---------10641065If the LZMA decoder has decoded the value "1" with IsRep[state] variable,1066we have "Rep Match" type.10671068At first the LZMA decoder must check that it doesn't exceed1069specified uncompressed size:10701071if (unpackSizeDefined && unpackSize == 0)1072return LZMA_RES_ERROR;10731074Also the decoder must return error, if the LZ window is empty:10751076if (OutWindow.IsEmpty())1077return LZMA_RES_ERROR;10781079If the match type is "Rep Match", the decoder uses one of the 4 variables of1080distance history table to get the value of distance for current match.1081And there are 4 corresponding ways of decoding flow.10821083The decoder updates the distance history with the following scheme1084depending from type of match:10851086- "Rep Match 0" or "Short Rep Match":1087; LZMA doesn't update the distance history10881089- "Rep Match 1":1090UInt32 dist = rep1;1091rep1 = rep0;1092rep0 = dist;10931094- "Rep Match 2":1095UInt32 dist = rep2;1096rep2 = rep1;1097rep1 = rep0;1098rep0 = dist;10991100- "Rep Match 3":1101UInt32 dist = rep3;1102rep3 = rep2;1103rep2 = rep1;1104rep1 = rep0;1105rep0 = dist;11061107Then the decoder decodes exact subtype of "Rep Match" using "IsRepG0", "IsRep0Long",1108"IsRepG1", "IsRepG2".11091110If the subtype is "Short Rep Match", the decoder updates the state, puts1111the one byte from window to current position in window and goes to next1112MATCH/LITERAL symbol (the begin of main loop):11131114state = UpdateState_ShortRep(state);1115OutWindow.PutByte(OutWindow.GetByte(rep0 + 1));1116unpackSize--;1117continue;11181119In other cases (Rep Match 0/1/2/3), it decodes the zero-based1120length of match with "RepLenDecoder" decoder:11211122len = RepLenDecoder.Decode(&RangeDec, posState);11231124Then it updates the state:11251126state = UpdateState_Rep(state);11271128Then the decoder must copy match bytes as described in1129"The Match symbols copying" section.113011311132The match symbols copying1133-------------------------11341135If we have the match (Simple Match or Rep Match 0/1/2/3), the decoder must1136copy the sequence of bytes with calculated match distance and match length.1137If uncompressed size is defined, LZMA decoder must check that it doesn't1138exceed that specified uncompressed size:11391140len += kMatchMinLen;1141bool isError = false;1142if (unpackSizeDefined && unpackSize < len)1143{1144len = (unsigned)unpackSize;1145isError = true;1146}1147OutWindow.CopyMatch(rep0 + 1, len);1148unpackSize -= len;1149if (isError)1150return LZMA_RES_ERROR;11511152Then the decoder must go to the begin of main loop to decode next MATCH or LITERAL.1153115411551156NOTES1157-----11581159This specification doesn't describe the variant of decoder implementation1160that supports partial decoding. Such partial decoding case can require some1161changes in "end of stream" condition checks code. Also such code1162can use additional status codes, returned by decoder.11631164This specification uses C++ code with templates to simplify describing.1165The optimized version of LZMA decoder doesn't need templates.1166Such optimized version can use just two arrays of CProb variables:11671) The dynamic array of CProb variables allocated for the Literal Decoder.11682) The one common array that contains all other CProb variables.116911701171References:117211731. G. N. N. Martin, Range encoding: an algorithm for removing redundancy1174from a digitized message, Video & Data Recording Conference,1175Southampton, UK, July 24-27, 1979.117611771178