Lempel–Ziv–Markov chain algorithm
   HOME

TheInfoList



OR:

The Lempel–Ziv–Markov chain algorithm (LZMA) is an
algorithm In mathematics and computer science, an algorithm () is a finite sequence of Rigour#Mathematics, mathematically rigorous instructions, typically used to solve a class of specific Computational problem, problems or to perform a computation. Algo ...
used to perform
lossless data compression Lossless compression is a class of data compression that allows the original data to be perfectly reconstructed from the compressed data with no loss of information. Lossless compression is possible because most real-world data exhibits Redundanc ...
. It has been used in the 7z format of the
7-Zip 7-Zip is a free and open-source file archiver, a utility used to place groups of files within compressed containers known as "archives". It is developed by Igor Pavlov and was first released in 1999. 7-Zip has its own Archive file, archive forma ...
archiver since 2001. This algorithm uses a dictionary compression scheme somewhat similar to the
LZ77 LZ77 and LZ78 are the two lossless data compression algorithms published in papers by Abraham Lempel and Jacob Ziv in 1977 and 1978. They are also known as Lempel-Ziv 1 (LZ1) and Lempel-Ziv 2 (LZ2) respectively. These two algorithms form the basis ...
algorithm published by
Abraham Lempel Abraham Lempel (; 10 February 1936 – 4 February 2023) was an Israeli computer scientist and one of the fathers of the LZ family of lossless data compression algorithms. Biography Lempel was born on 10 February 1936 in Lwów, Poland (now Lviv ...
and
Jacob Ziv Jacob Ziv (; 27 November 1931 – 25 March 2023) was an Israeli electrical engineer and information theorist who developed the LZ family of lossless data compression algorithms alongside Abraham Lempel. He is also a namesake of the Ziv–Zakai ...
in 1977 and features a high compression ratio (generally higher than
bzip2 bzip2 is a free and open-source file compression program that uses the Burrows–Wheeler algorithm. It only compresses single files and is not a file archiver. It relies on separate external utilities such as tar for tasks such as handli ...
) - 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. and a variable compression-dictionary size (up to 4  GB), while still maintaining decompression speed similar to other commonly used compression algorithms. 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.


Overview

LZMA uses a dictionary compression algorithm (a variant of
LZ77 LZ77 and LZ78 are the two lossless data compression algorithms published in papers by Abraham Lempel and Jacob Ziv in 1977 and 1978. They are also known as Lempel-Ziv 1 (LZ1) and Lempel-Ziv 2 (LZ2) respectively. These two algorithms form the basis ...
with huge dictionary sizes and special support for repeatedly used match distances), whose output is then encoded with a range 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 a dynamic programming algorithm is used to select an optimal one under certain approximations. 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 in zip and
gzip gzip is a file format and a software application used for file compression and decompression. The program was created by Jean-loup Gailly and Mark Adler as a free software replacement for the compress program used in early Unix systems, and ...
formats), the dictionary sizes can be and usually are much larger, taking advantage of the large amount of memory available on modern systems.


Compressed format overview

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 and the LZMA SDK documentation describe this stream format. There are 7 types of packets: LONGREP refers to LONGREP –3packets, *REP refers to both LONGREP and SHORTREP, and *MATCH refers to both MATCH and *REP. LONGREP 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 don't alter the list. The length is encoded as follows: 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).


Decompression algorithm details

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 compact XZ Embedded decoder by Lasse Collin included in the Linux kernel source 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

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 variable ''prob'' (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 to , 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), and ''code'' (representing the encoded point within the range). Initialization of the range decoder consists of setting ''range'' to , and ''code'' 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: # Shift both ''range'' and ''code'' left by 8 bits # Read a byte from the compressed stream # Set the least significant 8 bits of ''code'' to the byte value read Context-based range decoding of a bit using the ''prob'' probability variable proceeds in this way: # If ''range'' is less than , perform normalization # Set ''bound'' to # If ''code'' is less than ''bound'': ## Set ''range'' to ''bound'' ## Set ''prob'' to ''prob'' + ## Return bit 0 # Otherwise (if ''code'' is greater than or equal to the ''bound''): ## Set ''range'' to ''range'' − ''bound'' ## Set ''code'' to ''code'' − ''bound'' ## Set ''prob'' to ## Return bit 1 Fixed-probability range decoding of a bit proceeds in this way: # If ''range'' is less than , perform normalization # Set ''range'' to # If ''code'' is less than ''range'': ## Return bit 0 # Otherwise (if ''code'' is greater or equal than ''range''): ## Set ''code'' to ''code'' − ''range'' ## Return bit 1 The Linux kernel implementation of fixed-probability decoding in rc_direct(), for performance reasons, does not include a conditional branch, but instead subtracts ''range'' from ''code'' unconditionally. The resulting sign bit is used to both decide the bit to return and to generate a mask that is combined with ''code'' and added to ''range''. Note that: # The division by when computing ''bound'' 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) # Fixed probability decoding is not strictly equivalent to context-based range decoding with any ''prob'' value, due to the fact that context-based range decoding discards the lower 11 bits of ''range'' before multiplying by ''prob'' as just described, while fixed probability decoding only discards the last bit


Range coding of integers

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 than ''limit'', an array of 11-bit probability variables is provided, which are conceptually arranged as the internal nodes of a complete binary tree with ''limit'' 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 two ''limit'', and reversing the last bits of the result. In the function in the Linux kernel, integers are actually returned in the range (with ''limit'' 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 2''i'' and 2''i'' + 1. The function instead adds integers in the range to a caller-provided variable, where ''limit'' 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

The LZMA decoder is configured by an "properties" byte and a dictionary size. The value of the byte is ''lc'' + ''lp'' * 9 + ''pb'' * 9 * 5, where: * 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) * is the number of low bits of the dictionary position to include in (the default value used by the LZMA SDK is 0) * is the number of low bits of the dictionary position to include in (the default value used by the LZMA SDK is 2) In non-LZMA2 streams, must not be greater than 8, and and must not be greater than 4. In LZMA2 streams, ''lc'' + ''lp'' and must not be greater than 4. 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

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. The 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. The and values consist of respectively the and (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. The value is set to the (up to 4, from the LZMA header or LZMA2 properties packet) most significant bits of the previous uncompressed byte. The value denotes whether a packet that includes a length is a LONGREP rather than a MATCH. The 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. 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 in , while otherwise it is 0; the choice between the 1 or 2 values depends on the value of the bit at the same position in . 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 the 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 with 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:


LZMA2 format

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. 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 2''v''/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 * The ''state'' 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

The . xz format, which can contain LZMA2 data, is documented at ''tukaani.org'', 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.


7-Zip reference implementation

The LZMA implementation extracted from
7-Zip 7-Zip is a free and open-source file archiver, a utility used to place groups of files within compressed containers known as "archives". It is developed by Igor Pavlov and was first released in 1999. 7-Zip has its own Archive file, archive forma ...
is available as LZMA SDK. It was originally dual-licensed under both the
GNU LGPL The GNU Lesser General Public License (LGPL) is a free-software license published by the Free Software Foundation (FSF). The license allows developers and companies to use and integrate a software component released under the LGPL into their own ...
and
Common Public License In computing, the Common Public License (CPL) is a free software / open-source software license published by IBM. The Free Software Foundation and Open Source Initiative have approved the license terms of the CPL. Definition The CPL has the stat ...
, with an additional special exception for linked binaries, but was placed by Igor Pavlov in the
public domain The public domain (PD) consists of all the creative work to which no Exclusive exclusive intellectual property rights apply. Those rights may have expired, been forfeited, expressly Waiver, waived, or may be inapplicable. Because no one holds ...
on December 2, 2008, with the release of version 4.62. LZMA2 compression, which is an improved version of LZMA, is now the default compression method for the .7z format, starting with version 9.30 on October 26, 2012. The reference
open source Open source is source code that is made freely available for possible modification and redistribution. Products include permission to use and view the source code, design documents, or content of the product. The open source model is a decentrali ...
LZMA compression library was originally written in C++ but has been ported to
ANSI C ANSI C, ISO C, and Standard C are successive standards for the C programming language published by the American National Standards Institute (ANSI) and ISO/IEC JTC 1/SC 22/WG 14 of the International Organization for Standardization (ISO) and the ...
, C#, and
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
. There are also third-party
Python Python may refer to: Snakes * Pythonidae, a family of nonvenomous snakes found in Africa, Asia, and Australia ** ''Python'' (genus), a genus of Pythonidae found in Africa and Asia * Python (mythology), a mythical serpent Computing * Python (prog ...
bindings for the C++ library, as well as ports of LZMA to Pascal, Go and Ada. The 7-Zip implementation uses several variants of
hash chain A hash chain is the successive application of a cryptographic hash function to a piece of data. In computer security, a hash chain is a method used to produce many one-time keys from a single key or password. For non-repudiation, a hash functi ...
s,
binary tree In computer science, a binary tree is a tree data structure in which each node has at most two children, referred to as the ''left child'' and the ''right child''. That is, it is a ''k''-ary tree with . A recursive definition using set theor ...
s and
Patricia tree In computer science, a radix tree (also radix trie or compact prefix tree or compressed trie) is a data structure that represents a space-optimized trie (prefix tree) in which each node that is the only child is merged with its parent. The resul ...
s as the basis for its dictionary search algorithm. In addition to LZMA, the SDK and 7-Zip also implements multiple preprocessing filters intended to improve compression, ranging from simple
delta encoding Delta encoding is a way of storing or transmitting data in the form of '' differences'' (deltas) between sequential data rather than complete files; more generally this is known as data differencing. Delta encoding is sometimes called delta comp ...
(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 the
sliding window A sliding window protocol is a feature of packet-based data transmission Protocol (computing), protocols. Sliding window protocols are used where reliable in-order delivery of packets is required, such as in the data link layer (OSI model#Laye ...
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 to embedded applications.


Other implementations

In addition to the 7-Zip reference implementation, the following support the LZMA format. * xz: a streaming implementation that contains a
gzip gzip is a file format and a software application used for file compression and decompression. The program was created by Jean-loup Gailly and Mark Adler as a free software replacement for the compress program used in early Unix systems, and ...
-like command line tool, supporting both LZMA and LZMA2 in its xz file format. It made its way into several software of the
Unix-like A Unix-like (sometimes referred to as UN*X, *nix or *NIX) operating system is one that behaves in a manner similar to a Unix system, although not necessarily conforming to or being certified to any version of the Single UNIX Specification. A Uni ...
world with its high performance (compared to
bzip2 bzip2 is a free and open-source file compression program that uses the Burrows–Wheeler algorithm. It only compresses single files and is not a file archiver. It relies on separate external utilities such as tar for tasks such as handli ...
) and small size (compared to
gzip gzip is a file format and a software application used for file compression and decompression. The program was created by Jean-loup Gailly and Mark Adler as a free software replacement for the compress program used in early Unix systems, and ...
). The
Linux kernel The Linux kernel is a Free and open-source software, free and open source Unix-like kernel (operating system), kernel that is used in many computer systems worldwide. The kernel was created by Linus Torvalds in 1991 and was soon adopted as the k ...
,
dpkg dpkg is the software at the base of the package management system in the free software, free operating system Debian and its numerous Debian family, derivatives. dpkg is used to install, remove, and provide information about deb (file format), . ...
and
RPM Revolutions per minute (abbreviated rpm, RPM, rev/min, r/min, or r⋅min−1) is a unit of rotational speed (or rotational frequency) for rotating machines. One revolution per minute is equivalent to hertz. Standards ISO 80000-3:2019 def ...
systems contains xz code, and many software distributors like
kernel.org kernel.org on the World Wide Web is the main distribution point of source code for the Linux kernel, which is the base of the Linux operating system. The website and related infrastructure, which is operated by the Linux Kernel Organization, ho ...
,
Debian Debian () is a free and open-source software, free and open source Linux distribution, developed by the Debian Project, which was established by Ian Murdock in August 1993. Debian is one of the oldest operating systems based on the Linux kerne ...
and
Fedora A fedora () is a hat with a soft brim and indented crown.Kilgour, Ruth Edwards (1958). ''A Pageant of Hats Ancient and Modern''. R. M. McBride Company. It is typically creased lengthwise down the crown and "pinched" near the front on both sides ...
now use xz for compressing their releases. *
lzip lzip is a free, command-line tool for the compression of data; it employs the Lempel–Ziv–Markov chain algorithm (LZMA) with a user interface that is familiar to users of usual Unix compression tools, such as gzip and bzip2. Like gzip and ...
: another LZMA implementation mostly for Unix-like systems that is an alternative to xz. It features a simpler file format with easier error recovery. * ZIPX: an extension to the ZIP compression format that was created by
WinZip WinZip is a trialware file archiver and data compression, compressor for Microsoft Windows, macOS, iOS and Android (operating system), Android. It is developed by WinZip Computing (formerly Nico Mak Computing), which is owned by Alludo. The p ...
starting with version 12.1. It also can use various other compression methods such as
BZip bzip2 is a free and open-source file compression program that uses the Burrows–Wheeler algorithm. It only compresses single files and is not a file archiver. It relies on separate external utilities such as tar for tasks such as handli ...
and PPMd.


References


External links


Official home page







LZMA Utils = XZ Utils

Windows Binaries for XZ Utils

Data compression, Compressors & Archivers
{{Compression Methods Lossless compression algorithms Israeli inventions Data compression