Most LZ77 derived algorithms split input data into blocks of uncompressed data (called literal blocks) and back-references (pairs of offsets and lengths)
that state "add length bytes that are the same as those already written starting offset bytes before the current position. The details of how
those blocks and back-references are encoded are quite different between the algorithms and some algorithms perform additional steps (Huffman encoding in the
case of DEFLATE for example).
This class attempts to extract the core logic - finding back-references - so it can be re-used. It follows the algorithm explained in section 4 of RFC 1951 (DEFLATE) and currently doesn't implement the "lazy match" optimization. The three-byte hash function used in this class is the same as the one used by zlib and InfoZIP's ZIP implementation of DEFLATE. The whole class is strongly inspired by InfoZIP's implementation.
LZ77 is used vaguely here (as well as many other places that talk about it :-), LZSS would likely be closer to the truth but LZ77 has become the synonym for a whole family of algorithms.
The API consists of a compressor that is fed bytes and emits Blocks to a registered callback where the blocks represent either
literal blocks, back-references or end of data markers. In order to ensure the callback receives all
information, the #finish method must be used once all data has been fed into the compressor.
Several parameters influence the outcome of the "compression":
windowSizewindowSize - real world values are in the area of 32k.minBackReferenceLengthmaxBackReferenceLengthmaxOffsetmaxLiteralLength| Modifier and Type | Class and Description |
|---|---|
| public static class | LZ77Compressor.BackReference
Represents a back-reference. |
| public abstract static class | LZ77Compressor.Block
Base class representing blocks the compressor may emit. |
| public static interface | LZ77Compressor.Callback
Callback invoked while the compressor processes data. |
| public static class | LZ77Compressor.EOD
A simple "we are done" marker. |
| public static class | LZ77Compressor.LiteralBlock
Represents a literal block of data. |
| Modifier and Type | Field and Description |
|---|---|
| private int | |
| private final LZ77Compressor. | |
| private int | |
| private static final int | |
| private static final int | |
| private static final int | |
| private final int[] | |
| private boolean | |
| private int | |
| private int | |
| private int | |
| private int | |
| private static final int | |
| pack-priv static final int | |
| private final Parameters | |
| private final int[] | |
| private static final LZ77Compressor. | |
| private final byte[] | |
| private final int |
| Access | Constructor and Description |
|---|---|
| public | LZ77Compressor(final Parameters
the parameters params, final LZ77Compressor.the callback callbackInitializes a compressor with parameters and a callback. |
| Modifier and Type | Method and Description |
|---|---|
| private void | |
| private void | |
| public void | compress(final byte[]
the data to compress - must not be null data)Feeds bytes into the compressor which in turn may emit zero or more blocks to the callback during the execution of this method. |
| public void | compress(final byte[]
the data to compress - must not be null data, int the start offset of the data off, int the number of bytes to compress len)Feeds bytes into the compressor which in turn may emit zero or more blocks to the callback during the execution of this method. |
| private void | |
| public void | |
| private void | |
| private void | |
| private void | |
| private int | insertString(final int pos)
Inserts the current three byte sequence into the dictionary and returns the previous head of the hash-chain. |
| private void | |
| private int | longestMatch(int matchHead)
Searches the hash chain for real matches and returns the length of the longest match (0 if none were found) that isn't too far away (WRT maxOffset). |
| private int | |
| private int | nextHash(final int oldHash, final byte nextByte)
Assumes we are calculating the hash for three consecutive bytes as a rolling hash, i.e. for bytes ABCD if H is the hash of ABC the new hash for BCD is nextHash(H, D). |
| public void | prefill(final byte[]
the data to fill the window with. data)Adds some initial data to fill the window with. |
| private void |
| blockStart | back to summary |
|---|---|
| private int blockStart | |
| callback | back to summary |
|---|---|
| private final LZ77Compressor. | |
| currentPosition | back to summary |
|---|---|
| private int currentPosition | |
| H_SHIFT | back to summary |
|---|---|
| private static final int H_SHIFT | |
| HASH_MASK | back to summary |
|---|---|
| private static final int HASH_MASK | |
| HASH_SIZE | back to summary |
|---|---|
| private static final int HASH_SIZE | |
| head | back to summary |
|---|---|
| private final int[] head | |
| initialized | back to summary |
|---|---|
| private boolean initialized | |
| insertHash | back to summary |
|---|---|
| private int insertHash | |
| lookahead | back to summary |
|---|---|
| private int lookahead | |
| matchStart | back to summary |
|---|---|
| private int matchStart | |
| missedInserts | back to summary |
|---|---|
| private int missedInserts | |
| NO_MATCH | back to summary |
|---|---|
| private static final int NO_MATCH | |
| NUMBER_OF_BYTES_IN_HASH | back to summary |
|---|---|
| pack-priv static final int NUMBER_OF_BYTES_IN_HASH | |
| params | back to summary |
|---|---|
| private final Parameters params | |
| prev | back to summary |
|---|---|
| private final int[] prev | |
| THE_EOD | back to summary |
|---|---|
| private static final LZ77Compressor. | |
| window | back to summary |
|---|---|
| private final byte[] window | |
| wMask | back to summary |
|---|---|
| private final int wMask | |
| LZ77Compressor | back to summary |
|---|---|
| public LZ77Compressor(final Parameters params, final LZ77Compressor. Initializes a compressor with parameters and a callback.
| |
| catchUpMissedInserts | back to summary |
|---|---|
| private void catchUpMissedInserts() | |
| compress | back to summary |
|---|---|
| private void compress() throws IOException | |
| compress | back to summary |
|---|---|
| public void compress(final byte[] data) throws IOException Feeds bytes into the compressor which in turn may emit zero or more blocks to the callback during the execution of this method.
| |
| compress | back to summary |
|---|---|
| public void compress(final byte[] data, int off, int len) throws IOException Feeds bytes into the compressor which in turn may emit zero or more blocks to the callback during the execution of this method.
| |
| doCompress | back to summary |
|---|---|
| private void doCompress(final byte[] data, final int off, final int len) throws IOException | |
| finish | back to summary |
|---|---|
| public void finish() throws IOException Tells the compressor to process all remaining data and signal end of data to the callback.
The compressor will in turn emit at least one block (
| |
| flushBackReference | back to summary |
|---|---|
| private void flushBackReference(final int matchLength) throws IOException | |
| flushLiteralBlock | back to summary |
|---|---|
| private void flushLiteralBlock() throws IOException | |
| initialize | back to summary |
|---|---|
| private void initialize() | |
| insertString | back to summary |
|---|---|
| private int insertString(final int pos) Inserts the current three byte sequence into the dictionary and returns the previous head of the hash-chain.
Updates | |
| insertStringsInMatch | back to summary |
|---|---|
| private void insertStringsInMatch(final int matchLength) | |
| longestMatch | back to summary |
|---|---|
| private int longestMatch(int matchHead) Searches the hash chain for real matches and returns the length of the longest match (0 if none were found) that isn't too far away (WRT maxOffset). Sets matchStart to the index of the start position of the longest match as a side effect. | |
| longestMatchForNextPosition | back to summary |
|---|---|
| private int longestMatchForNextPosition(final int prevMatchLength) | |
| nextHash | back to summary |
|---|---|
| private int nextHash(final int oldHash, final byte nextByte) Assumes we are calculating the hash for three consecutive bytes as a rolling hash, i.e. for bytes ABCD if H is the hash of ABC the new hash for BCD is nextHash(H, D). The hash is shifted by five bits on each update so all effects of A have been swapped after the third update. | |
| prefill | back to summary |
|---|---|
| public void prefill(final byte[] data) Adds some initial data to fill the window with. This is used if the stream has been cut into blocks and back-references of one block may refer to data of the previous block(s). One such example is the LZ4 frame format using block dependency.
| |
| slide | back to summary |
|---|---|
| private void slide() throws IOException | |
| Modifier and Type | Field and Description |
|---|---|
| private final int | |
| private final int |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public int | |
| public int | |
| public LZ77Compressor. | getType()
Implements abstract org. |
| public String |
| length | back to summary |
|---|---|
| private final int length | |
| offset | back to summary |
|---|---|
| private final int offset | |
| BackReference | back to summary |
|---|---|
| public BackReference(final int offset, final int length) | |
| getLength | back to summary |
|---|---|
| public int getLength() Provides the length of the back-reference.
| |
| getOffset | back to summary |
|---|---|
| public int getOffset() Provides the offset of the back-reference.
| |
| getType | back to summary |
|---|---|
| public LZ77Compressor. Implements abstract org.
| |
| toString | back to summary |
|---|---|
| public String toString() Overrides java. Doc from java. Returns a string representation of the object. | |
This class is not supposed to be subclassed by classes outside of Commons Compress so it is considered internal and changed that would break subclasses may get introduced with future releases.
| Modifier and Type | Class and Description |
|---|---|
| public static enum | LZ77Compressor.Block.BlockType
Enumeration of the block types the compressor may emit. |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public abstract LZ77Compressor. |
| Block | back to summary |
|---|---|
| public Block() | |
| getType | back to summary |
|---|---|
| public abstract LZ77Compressor. | |
| Modifier and Type | Field and Description |
|---|---|
| public static final LZ77Compressor. | |
| public static final LZ77Compressor. | |
| public static final LZ77Compressor. |
| Access | Constructor and Description |
|---|---|
| private |
| Modifier and Type | Method and Description |
|---|---|
| public static LZ77Compressor. | |
| public static LZ77Compressor. |
| BACK_REFERENCE | back to summary |
|---|---|
| public static final LZ77Compressor. | |
| EOD | back to summary |
|---|---|
| public static final LZ77Compressor. | |
| LITERAL | back to summary |
|---|---|
| public static final LZ77Compressor. | |
| BlockType | back to summary |
|---|---|
| private BlockType() | |
| valueOf | back to summary |
|---|---|
| public static LZ77Compressor. | |
| values | back to summary |
|---|---|
| public static LZ77Compressor. | |
The callback is invoked on the same thread that receives the bytes to compress and may be invoked multiple times during the execution of
compress or finish.
| Modifier and Type | Method and Description |
|---|---|
| public void |
| accept | back to summary |
|---|---|
| public void accept(LZ77Compressor. Consumes a block.
| |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public LZ77Compressor. | getType()
Implements abstract org. |
| EOD | back to summary |
|---|---|
| public EOD() | |
| getType | back to summary |
|---|---|
| public LZ77Compressor. Implements abstract org.
| |
For performance reasons this encapsulates the real data, not a copy of it. Don't modify the data and process it inside of Callback#accept
immediately as it will get overwritten sooner or later.
| Modifier and Type | Field and Description |
|---|---|
| private final byte[] | |
| private final int | |
| private final int |
| Access | Constructor and Description |
|---|---|
| public |
| Modifier and Type | Method and Description |
|---|---|
| public byte[] | |
| public int | |
| public int | |
| public LZ77Compressor. | getType()
Implements abstract org. |
| public String |
| data | back to summary |
|---|---|
| private final byte[] data | |
| length | back to summary |
|---|---|
| private final int length | |
| offset | back to summary |
|---|---|
| private final int offset | |
| LiteralBlock | back to summary |
|---|---|
| public LiteralBlock(final byte[] data, final int offset, final int length) | |
| getData | back to summary |
|---|---|
| public byte[] getData() The literal data. This returns a life view of the actual data in order to avoid copying, modify the array at your own risk.
| |
| getLength | back to summary |
|---|---|
| public int getLength() Length of literal block.
| |
| getOffset | back to summary |
|---|---|
| public int getOffset() Offset into data where the literal block starts.
| |
| getType | back to summary |
|---|---|
| public LZ77Compressor. Implements abstract org.
| |
| toString | back to summary |
|---|---|
| public String toString() Overrides java. Doc from java. Returns a string representation of the object. | |