35e69fc7cf
* New feature: "Large Window Brotli" By setting special encoder/decoder flag it is now possible to extend LZ-window up to 30 bits; though produced stream will not be RFC7932 compliant. Added new dictionary generator - "DSH". It combines speed of "Sieve" and quality of "DM". Plus utilities to prepare train corpora (remove unique strings). Improved compression ratio: now two sub-blocks could be stitched: the last copy command could be extended to span the next sub-block. Fixed compression ineffectiveness caused by floating numbers rounding and wrong cost heuristic. Other C changes: - combined / moved `context.h` to `common` - moved transforms to `common` - unified some aspects of code formatting - added an abstraction for encoder (static) dictionary - moved default allocator/deallocator functions to `common` brotli CLI: - window size is auto-adjusted if not specified explicitly Java: - added "eager" decoding both to JNI wrapper and pure decoder - huge speed-up of `DictionaryData` initialization * Add dictionaryless compressed dictionary * Fix `sources.lst` * Fix `sources.lst` and add a note that `libtool` is also required. * Update setup.py * Fix `EagerStreamTest` * Fix BUILD file * Add missing `libdivsufsort` dependency * Fix "unused parameter" warning. |
||
---|---|---|
.. | ||
esaxx@ca7cb33201 | ||
img | ||
libdivsufsort@5f60d6f026 | ||
brotlidump.py | ||
BUILD | ||
BUILD.libdivsufsort | ||
deorummolae.cc | ||
deorummolae.h | ||
dictionary_generator.cc | ||
draw_diff.cc | ||
draw_histogram.cc | ||
durchschlag.cc | ||
durchschlag.h | ||
find_opt_references.cc | ||
Makefile | ||
read_dist.h | ||
README.md | ||
sieve.cc | ||
sieve.h |
Introduction
In this directory we publish simple tools to analyze backward reference distance distributions in LZ77 compression. We developed these tools to be able to make more efficient encoding of distances in large-window brotli. In large-window compression the average cost of a backward reference distance is higher, and this may allow for more advanced encoding strategies, such as delta coding or an increase in context size, to bring significant compression density improvements. Our tools visualize the backward references as histogram images, i.e., one pixel in the image shows how many distances of a certain range exist at a certain locality in the data. The human visual system is excellent at pattern detection, so we tried to roughly identify patterns visually before going into more quantitative analysis. These tools can turn out to be useful in development of other LZ77-based compressors and we hope you try them out.
Tools
find_opt_references
This tool generates optimal (match-length-wise) backward references for every position in the input files and stores them in *.dist
file described below.
Example usage:
find_opt_references input.txt output.dist
draw_histogram
This tool generates a visualization of the distribution of backward references stored in *.dist
file. The original file size has to be specified as a second parameter. The output is a grayscale PGM (binary) image.
Example usage:
draw_histogram input.dist 65536 output.pgm
Here's an example of resulting image:
draw_diff
This tool generates a diff PPM (binary) image between two input 8-bit PGM (binary) images. Input images must be of same size. Useful for comparing different backward references distributions for same input file. Normally used for comparison of output images from draw_histogram
tool.
Example usage:
draw_diff image1.pgm image2.pgm diff.ppm
For example the diff of this image
and this image
looks like this:
Backward distance file format
The format of *.dist
files is as follows:
[[ 0| match length][ 1|position|distance]...]
[1 byte| 4 bytes][1 byte| 4 bytes| 4 bytes]
More verbose explanation: for each backward reference there is a position-distance pair, also a copy length may be specified. Copy length is prefixed with flag byte 0, position-distance pair is prefixed with flag byte 1. Each number is a 32-bit integer. Copy length always comes before position-distance pair. Standalone copy length is allowed, in this case it is ignored.
Here's an example of how to read from *.dist
file:
#include "read_dist.h"
FILE* f;
int copy, pos, dist;
while (ReadBackwardReference(fin, ©, &pos, &dist)) {
...
}