Movatterモバイル変換


[0]ホーム

URL:


Jump to content
WikipediaThe Free Encyclopedia
Search

LZMA

From Wikipedia, the free encyclopedia
Lossless data compression algorithm
For the airport with the ICAO code "LZMA", seeMartin Airport (Slovakia).

TheLempel–Ziv–Markov chain algorithm[1] (LZMA) is analgorithm used to performlossless data compression. It has been used in the7z format of the7-Zip archiver since 2001.[2] This algorithm uses adictionary compression scheme somewhat similar to theLZ77 algorithm published byAbraham Lempel andJacob Ziv in 1977 and features a high compression ratio (generally higher thanbzip2)[3][4] and a variable compression-dictionary size (up to 4 GB),[5] while still maintaining decompression speed similar to other commonly used compression algorithms.[6]

LZMA2 is a simple container format that can include both uncompressed data and LZMA data, possibly with multiple different LZMA encoding parameters. LZMA2 supports arbitrarily scalable multithreaded compression and decompression and efficient compression of data which is partially incompressible.[7]

Overview

[edit]

LZMA uses adictionary compression algorithm (a variant ofLZ77 with huge dictionary sizes and special support for repeatedly used match distances), whose output is then encoded with arange encoder, using a complex model to make a probability prediction of each bit. The dictionary compressor finds matches using sophisticated dictionary data structures, and produces a stream of literal symbols and phrase references, which is encoded one bit at a time by the range encoder: many encodings are possible, and adynamic programming algorithm is used to select an optimal one under certain approximations.[8]

Prior to LZMA, most encoder models were purely byte-based (i.e. they coded each bit using only a cascade of contexts to represent the dependencies on previous bits from the same byte). The main innovation of LZMA is that instead of a generic byte-based model, LZMA's model uses contexts specific to the bitfields in each representation of a literal or phrase: this is nearly as simple as a generic byte-based model, but gives much better compression because it avoids mixing unrelated bits together in the same context. Furthermore, compared to classic dictionary compression (such as the one used inzip andgzip formats), the dictionary sizes can be and usually are much larger, taking advantage of the large amount of memory available on modern systems.[8]

Compressed format overview

[edit]

In LZMA compression, the compressed stream is a stream of bits, encoded using an adaptive binary range coder. The stream is divided into packets, each packet describing either a single byte, or an LZ77 sequence with its length and distance implicitly or explicitly encoded. Each part of each packet is modeled with independent contexts, so the probability predictions for each bit are correlated with the values of that bit (and related bits from the same field) in previous packets of the same type.Both the lzip[9] and the LZMA SDK documentation describe this stream format.[8]

There are 7 types of packets:[9]

Packed code (bit sequence)Packet namePacket description
0 + byteCodeLITA single byte encoded using an adaptive binary range coder.
1+0 + len + distMATCHA typical LZ77 sequence describing sequence length and distance.
1+1+0+0SHORTREPA one-byte LZ77 sequence. Distance is equal to the last used LZ77 distance.
1+1+0+1 + lenLONGREP[0]An LZ77 sequence. Distance is equal to the last used LZ77 distance.
1+1+1+0 + lenLONGREP[1]An LZ77 sequence. Distance is equal to the second last used LZ77 distance.
1+1+1+1+0 + lenLONGREP[2]An LZ77 sequence. Distance is equal to the third last used LZ77 distance.
1+1+1+1+1 + lenLONGREP[3]An LZ77 sequence. Distance is equal to the fourth last used LZ77 distance.

LONGREP[*] refers to LONGREP[0–3] packets, *REP refers to both LONGREP and SHORTREP, and *MATCH refers to both MATCH and *REP.

LONGREP[n] packets remove the distance used from the list of the most recent distances and reinsert it at the front, to avoid useless repeated entry, while MATCH just adds the distance to the front even if already present in the list and SHORTREP and LONGREP[0] don't alter the list.

The length is encoded as follows:

Length code (bit sequence)Description
0+ 3 bitsThe length encoded using 3 bits, gives the lengths range from 2 to 9.
1+0+ 3 bitsThe length encoded using 3 bits, gives the lengths range from 10 to 17.
1+1+ 8 bitsThe length encoded using 8 bits, gives the lengths range from 18 to 273.

As in LZ77, the length is not limited by the distance, because copying from the dictionary is defined as if the copy was performed byte by byte, keeping the distance constant.

Distances are logically 32-bit and distance 0 points to the most recently added byte in the dictionary.

The distance encoding starts with a 6-bit "distance slot", which determines how many further bits are needed.Distances are decoded as a binary concatenation of, from most to least significant, two bits depending on the distance slot, some bits encoded with fixed 0.5 probability, and some context encoded bits, according to the following table (distance slots 0−3 directly encode distances 0−3).

Distance encoding[8]
6-bit distance slotHighest 2 bitsFixed 0.5 probability bitsContext encoded bits
00000
10100
21000
31100
41001
51101
61002
71102
81003
91103
101004
111104
121005
131105
14–62 (even)10slot / 2 − 54
15–63 (odd)11(slot − 1) / 2 − 54

Decompression algorithm details

[edit]
This sectionpossibly containsoriginal research. Pleaseimprove it byverifying the claims made and addinginline citations. Statements consisting only of original research should be removed.(April 2012) (Learn how and when to remove this message)

No complete natural language specification of the compressed format seems to exist, other than the one attempted in the following text.

The description below is based on the compactXZ Embedded decoder by Lasse Collin included in the Linux kernel source[10] from which the LZMA and LZMA2 algorithm details can be relatively easily deduced: thus, while citing source code as reference is not ideal, any programmer should be able to check the claims below with a few hours of work.

Range coding of bits

[edit]

LZMA data is at the lowest level decoded one bit at a time by the range decoder, at the direction of the LZMA decoder.

Context-based range decoding is invoked by the LZMA algorithm passing it a reference to the "context", which consists of the unsigned 11-bit variableprob (typically implemented using a 16-bit data type) representing the predicted probability of the bit being 0, which is read and updated by the range decoder (and should be initialized to210{\displaystyle 2^{10}}, representing 0.5 probability).

Fixed probability range decoding instead assumes a 0.5 probability, but operates slightly differently from context-based range decoding.

The range decoder state consists of two unsigned 32-bit variables,range (representing the range size), andcode (representing the encoded point within the range).

Initialization of the range decoder consists of settingrange to232 − 1, andcode to the 32-bit value starting at the second byte in the stream interpreted as big-endian; the first byte in the stream is completely ignored.

Normalization proceeds in this way:

  1. Shift bothrange andcode left by 8 bits
  2. Read a byte from the compressed stream
  3. Set the least significant 8 bits ofcode to the byte value read

Context-based range decoding of a bit using theprob probability variable proceeds in this way:

  1. Ifrange is less than224{\displaystyle 2^{24}}, perform normalization
  2. Setbound torange/211×prob{\displaystyle \lfloor range/2^{11}\rfloor \times prob}
  3. Ifcode is less thanbound:
    1. Setrange tobound
    2. Setprob toprob +211prob/25{\displaystyle \lfloor 2^{11}-prob\rfloor /2^{5}}
    3. Return bit 0
  4. Otherwise (ifcode is greater than or equal to thebound):
    1. Setrange torangebound
    2. Setcode tocodebound
    3. Setprob toprobprob/25{\displaystyle prob-\lfloor prob/2^{5}\rfloor }
    4. Return bit 1

Fixed-probability range decoding of a bit proceeds in this way:

  1. Ifrange is less than224{\displaystyle 2^{24}}, perform normalization
  2. Setrange torange/2{\displaystyle \lfloor range/2\rfloor }
  3. Ifcode is less thanrange:
    1. Return bit 0
  4. Otherwise (ifcode is greater or equal thanrange):
    1. Setcode tocoderange
    2. Return bit 1

The Linux kernel implementation of fixed-probability decoding inrc_direct(), for performance reasons, does not include a conditional branch, but instead subtractsrange fromcode unconditionally. The resulting sign bit is used to both decide the bit to return and to generate a mask that is combined withcode and added torange.

Note that:

  1. The division by211{\displaystyle 2^{11}} when computingbound and floor operation is done before the multiplication, not after (apparently to avoid requiring fast hardware support for 32-bit multiplication with a 64-bit result)
  2. Fixed probability decoding is not strictly equivalent to context-based range decoding with anyprob value, due to the fact that context-based range decoding discards the lower 11 bits ofrange before multiplying byprob as just described, while fixed probability decoding only discards the last bit

Range coding of integers

[edit]

The range decoder also provides the bit-tree, reverse bit-tree and fixed probability integer decoding facilities, which are used to decode integers, and generalize the single-bit decoding described above.To decode unsigned integers less thanlimit, an array of(limit − 1) 11-bit probability variables is provided, which are conceptually arranged as the internal nodes of a complete binary tree withlimit leaves.

Non-reverse bit-tree decoding works by keeping a pointer to the tree of variables, which starts at the root. As long as the pointer does not point to a leaf, a bit is decoded using the variable indicated by the pointer, and the pointer is moved to either the left or right children depending on whether the bit is 0 or 1; when the pointer points to a leaf, the number associated with the leaf is returned.

Non-reverse bit-tree decoding thus happens from most significant to least significant bit, stopping when only one value in the valid range is possible (this conceptually allows to have range sizes that are not powers of two, even though LZMA does not make use of this).

Reverse bit-tree decoding instead decodes from least significant bit to most significant bits, and thus only supports ranges that are powers of two, and always decodes the same number of bits. It is equivalent to performing non-reverse bittree decoding with a power of twolimit, and reversing the lastlog2(limit) bits of the result.

In therc_bittree function in the Linux kernel, integers are actually returned in the[limit, 2 ×limit) range (withlimit added to the conceptual value), and the variable at index 0 in the array is unused, while the one at index 1 is the root, and the left and right children indices are computed as 2i and 2i + 1. Therc_bittree_reverse function instead adds integers in the[0,limit) range to a caller-provided variable, wherelimit is implicitly represented by its logarithm, and has its own independent implementation for efficiency reasons.

Fixed probability integer decoding simply performs fixed probability bit decoding repeatedly, reading bits from the most to the least significant.

LZMA configuration

[edit]

The LZMA decoder is configured by anlclppb "properties" byte and a dictionary size. The value of thelclppb byte islc +lp * 9 +pb * 9 * 5, where:

  • lc is the number of high bits of the previous byte to use as a context for literal encoding (the default value used by the LZMA SDK is 3)
  • lp is the number of low bits of the dictionary position to include inliteral_pos_state (the default value used by the LZMA SDK is 0)
  • pb is the number of low bits of the dictionary position to include inpos_state (the default value used by the LZMA SDK is 2)

In non-LZMA2 streams,lc must not be greater than 8, andlp andpb must not be greater than 4; this results in a range of 0 to 224. In LZMA2 streams,lc +lp andpb must not be greater than 4; this provides a much larger set of impossible values.

In the 7-zip LZMA file format, configuration is performed by a header containing the "properties" byte followed by the 32-bit little-endian dictionary size in bytes. In LZMA2, the properties byte can optionally be changed at the start of LZMA2 LZMA packets, while the dictionary size is specified in the LZMA2 header as later described.

LZMA coding contexts

[edit]

The LZMA packet format has already been described, and this section specifies how LZMA statistically models the LZ-encoded streams, or in other words which probability variables are passed to the range decoder to decode each bit.

Those probability variables are implemented as multi-dimensional arrays; before introducing them, a few values that are used as indices in these multidimensional arrays are defined.

Thestate value is conceptually based on which of the patterns in the following table match the latest 2–4 packet types seen, and is implemented as a state machine state updated according to the transition table listed in the table every time a packet is output.

The initial state is 0, and thus packets before the beginning are assumed to be LIT packets.

stateprevious packetsnext state when next packet is
4th previous3rd previous2nd previouspreviousLITMATCHLONGREP[*]SHORTREP
0LITLITLIT0789
1MATCHLITLIT0789
2LONGREP[*]LITLIT0789
*MATCHSHORTREP
3LITSHORTREPLITLIT0789
4MATCHLIT1789
5LONGREP[*]LIT2789
*MATCHSHORTREP
6LITSHORTREPLIT3789
7LITMATCH4101111
8LITLONGREP[*]5101111
9LITSHORTREP6101111
10*MATCHMATCH4101111
11*MATCH*REP5101111

Thepos_state andliteral_pos_state values consist of respectively thepb andlp (up to 4, from the LZMA header or LZMA2 properties packet) least significant bits of the dictionary position (the number of bytes coded since the last dictionary reset modulo the dictionary size). Note that the dictionary size is normally the multiple of a large power of 2, so these values are equivalently described as the least significant bits of the number of uncompressed bytes seen since the last dictionary reset.

Theprev_byte_lc_msbs value is set to thelc (up to 4, from the LZMA header or LZMA2 properties packet) most significant bits of the previous uncompressed byte.

Theis_REP value denotes whether a packet that includes a length is a LONGREP rather than a MATCH.

Thematch_byte value is the byte that would have been decoded if a SHORTREP packet had been used (in other words, the byte found at the dictionary at the last used distance); it is only used just after a *MATCH packet.

literal_bit_mode is an array of 8 values in the 0–2 range, one for each bit position in a byte, which are 1 or 2 if the previous packet was a *MATCH and it is either the most significant bit position or all the more significant bits in the literal to encode/decode are equal to the bits in the corresponding positions inmatch_byte, while otherwise it is 0; the choice between the 1 or 2 values depends on the value of the bit at the same position inmatch_byte.

The literal/Literal set of variables can be seen as a "pseudo-bit-tree" similar to a bit-tree but with 3 variables instead of 1 in every node, chosen depending on theliteral_bit_mode value at the bit position of the next bit to decode after the bit-tree context denoted by the node.

The claim, found in some sources, that literals after a *MATCH are coded as the XOR of the byte value withmatch_byte is incorrect; they are instead coded simply as their byte value, but using the pseudo-bit-tree just described and the additional context listed in the table below.

The probability variable groups used in LZMA are those:

XZ nameLZMA SDK nameParameterized byUsed whenCoding modeIf bit 0 thenIf bit 1 then
is_matchIsMatchstate,pos_statepacket startbitLIT*MATCH
is_repIsRepstateafter bit sequence 1bitMATCH*REP
is_rep0IsRepG0stateafter bit sequence 11bitSHORTREP/LONGREP[0]LONGREP[1–3]
is_rep0_longIsRep0Longstate,pos_stateafter bit sequence 110bitSHORTREPLONGREP[0]
is_rep1IsRepG1stateafter bit sequence 111bitLONGREP[1]LONGREP[2/3]
is_rep2IsRepG2stateafter bit sequence 1111bitLONGREP[2]LONGREP[3]
literalLiteralprev_byte_lc_msbs,literal_pos_state,literal_bit_mode[bit position], bit-tree contextafter bit sequence 0256 values pseudo-bit-treeliteral byte value
dist_slotPosSlotmin(match_length, 5), bit-tree contextdistance: start64 values bit-treedistance slot
dist_specialSpecPosdistance_slot, reverse bit-tree contextdistance: 4–13 distance slots((distance_slot >> 1) − 1)-bit reverse bit-treelow bits of distance
dist_alignAlignreverse bit-tree contextdistance: 14+ distance slots, after fixed probability bits4-bit reverse bit-treelow bits of distance
len_dec.choiceLenChoiceis_REPmatch length: startbit2–9 length10+ length
len_dec.choice2LenChoice2is_REPmatch length: after bit sequence 1bit10–17 length18+ length
len_dec.lowLenLowis_REP,pos_state, bit-tree contextmatch length: after bit sequence 08 values bit-treelow bits of length
len_dec.midLenMidis_REP,pos_state, bit-tree contextmatch length: after bit sequence 108 values bit-treemiddle bits of length
len_dec.highLenHighis_REP, bit-tree contextmatch length: after bit sequence 11256 values bit-treehigh bits of length

LZMA2 format

[edit]

The LZMA2 container supports multiple runs of compressed LZMA data and uncompressed data. Each LZMA compressed run can have a different LZMA configuration and dictionary. This improves the compression of partially or completely incompressible files and allows multithreaded compression and multithreaded decompression by breaking the file into runs that can be compressed or decompressed independently in parallel.Criticism of changes in LZMA2 over LZMA include header fields not being covered by CRCs,and parallel decompression not being possible in practice.[7]

The LZMA2 header consists of a byte indicating the dictionary size:

  • 40 indicates a 4 GB − 1 dictionary size
  • Even values less than 40 indicate a 2v/2 + 12 bytes dictionary size
  • Odd values less than 40 indicate a 3×2(v − 1)/2 + 11 bytes dictionary size
  • Values higher than 40 are invalid

LZMA2 data consists of packets starting with a control byte, with the following values:

  • 0 denotes the end of the file
  • 1 denotes a dictionary reset followed by an uncompressed chunk
  • 2 denotes an uncompressed chunk without a dictionary reset
  • 3–0x7f are invalid values
  • 0x80–0xff denotes an LZMA chunk, where the lowest 5 bits are used as bit 16–20 of the uncompressed size minus one, and bit 5–6 indicates what should be reset

Bits 5–6 for LZMA chunks can be:

  • 0: nothing reset
  • 1: state reset
  • 2: state reset, properties reset using properties byte
  • 3: state reset, properties reset using properties byte, dictionary reset

LZMA state resets cause a reset of all LZMA state except the dictionary, and specifically:

  • The range coder
  • Thestate value
  • The last distances for repeated matches
  • All LZMA probabilities

Uncompressed chunks consist of:

  • A 16-bit big-endian value encoding the data size minus one
  • The data to be copied verbatim into the dictionary and the output

LZMA chunks consist of:

  • A 16-bit big-endian value encoding the low 16 bits of the uncompressed size minus one
  • A 16-bit big-endian value encoding the compressed size minus one
  • A properties/lclppb byte if bit 6 in the control byte is set
  • The LZMA compressed data, starting with the 5 bytes (of which the first is ignored) used to initialize the range coder (which are included in the compressed size)

xz and 7z formats

[edit]

The .xz format, which can contain LZMA2 data, is documented attukaani.org,[11] while the .7z file format, which can contain either LZMA or LZMA2 data, is documented in the 7zformat.txt file contained in the LZMA SDK.[12]

7-Zip reference implementation

[edit]

The LZMA implementation extracted from7-Zip is available as LZMA SDK. It was originally dual-licensed under both theGNU LGPL andCommon Public License,[13] with an additional special exception for linked binaries, but was placed byIgor Pavlov in thepublic domain on December 2, 2008, with the release of version 4.62.[12]

LZMA2 compression, which is an improved version of LZMA,[14] is now the default compression method for the .7z format, starting with version 9.30 on October 26, 2012.[15]

The referenceopen source LZMA compression library was originally written inC++ but has been ported toANSI C,C#, andJava.[12] There are also third-partyPython bindings for the C++ library,[16] as well as ports of LZMA toPascal,[17]Go[18] andAda.[19]

The 7-Zip implementation uses several variants ofhash chains,binary trees andPatricia trees as the basis for its dictionary search algorithm.

In addition to LZMA, the SDK and 7-Zip also implements multiplepreprocessing filters intended to improve compression, ranging from simpledelta encoding (for images) and BCJ for executable code. It also provides some other compression algorithms used in 7z.

Decompression-only code for LZMA generally compiles to around 5 KB, and the amount of RAM required during decompression is principally determined by the size of thesliding window used during compression. Small code size and relatively low memory overhead, particularly with smaller dictionary lengths, and free source code make the LZMA decompression algorithm well-suited toembedded applications.

Other implementations

[edit]

In addition to the 7-Zip reference implementation, the following support the LZMA format.

  • xz: a streaming implementation that contains agzip-like command line tool, supporting both LZMA and LZMA2 in its xz file format. It made its way into several software of theUnix-like world with its high performance (compared tobzip2) and small size (compared togzip).[3] TheLinux kernel,dpkg andRPM systems contains xz code, and many software distributors likekernel.org,Debian[20] andFedora now use xz for compressing their releases.
  • lzip: another LZMA implementation mostly for Unix-like systems that is an alternative to xz.[21] It features a simpler file format with easier error recovery.
  • ZIPX: an extension to theZIP compression format that was created byWinZip starting with version 12.1. It also can use various other compression methods such asBZip andPPMd.[22]

References

[edit]
  1. ^Salomon, David (March 20, 2007).Data Compression: The Complete Reference. Springer London. p. 242.ISBN 9781846286032.
  2. ^Igor Pavlov (2001-12-05)."7z Format". Archived fromthe original on 5 December 2001.
  3. ^abLasse Collin (2005-05-31)."A Quick Benchmark: Gzip vs. Bzip2 vs. LZMA". Retrieved2015-10-21. - LZMA Unix Port was finally replaced by xz which features better and faster compression; from here we know even LZMA Unix Port was a lot better than gzip and bzip2.
  4. ^Klausmann, Tobias (2008-05-08)."Gzip, Bzip2 and Lzma compared".Blog of an Alpha animal. Archived fromthe original on 2013-01-06. Retrieved2013-06-16.
  5. ^Unknown (2013)."7z Format". Retrieved2013-06-16.
  6. ^Mahoney, Matt."Data Compression Explained". Retrieved2013-11-13.
  7. ^abAntonio Diaz Diaz."Xz format inadequate for long-term archiving". Retrieved2018-07-20.
  8. ^abcd"LZMA Specification.7z in LZMA SDK".7-zip.org.
  9. ^ab"Lzip Stream Format".Lzip Manual. Retrieved14 November 2019.
  10. ^Collin, Lasse; Pavlov, Igor."lib/xz/xz_dec_lzma2.c". Retrieved2013-06-16.
  11. ^"The .xz File Format". 2009-08-27. Retrieved2013-06-16.
  12. ^abcIgor Pavlov (2013)."LZMA SDK (Software Development Kit)". Retrieved2013-06-16.
  13. ^"Browse /LZMA SDK/4.23".SourceForge. Retrieved2014-02-12.
  14. ^"Inno Setup Help". jrsoftware.org. Retrieved2013-06-16.LZMA2 is a modified version of LZMA that offers a better compression ratio for uncompressible data (random data expands about 0.005%, compared to 1.35% with original LZMA), and optionally can compress multiple parts of large files in parallel, greatly increasing compression speed but with a possible reduction in compression ratio.
  15. ^"HISTORY of the 7-Zip". 2012-10-26. Retrieved2013-06-16.
  16. ^Bauch, Joachim (2010-04-07)."PyLZMA – Platform independent python bindings for the LZMA compression library". Retrieved2013-06-16.
  17. ^Birtles, Alan (2006-06-13)."Programming Help: Pascal LZMA SDK". Retrieved2013-06-16.
  18. ^Vieru, Andrei (2012-06-28)."compress/lzma package for Go 1". Archived fromthe original on 2016-09-21. Retrieved2013-06-16.
  19. ^"Zip-Ada".
  20. ^Guillem Jover."Accepted dpkg 1.17.0 (source amd64 all)".Debian Package QA. Retrieved2015-10-21.
  21. ^Diaz, Diaz."Lzip Benchmarks". LZIP (nongnu).
  22. ^"What is a Zipx File?". WinZip.com. Retrieved2016-03-14.

External links

[edit]
Archiving only
Compressing only
Archiving
and compressing
Software packaging
and distributing
Document packaging
and distributing
Lossless
type
Entropy
Dictionary
Other
Hybrid
Lossy
type
Transform
Predictive
Audio
Concepts
Codec
parts
Image
Concepts
Methods
Video
Concepts
Codec
parts
Theory
Community
People
Retrieved from "https://en.wikipedia.org/w/index.php?title=LZMA&oldid=1305067429"
Categories:
Hidden categories:

[8]ページ先頭

©2009-2025 Movatter.jp