• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..17-Nov-2021-

ci/H17-Nov-2021-12988

corrosion/H17-Nov-2021-5,2084,963

examples/H17-Nov-2021-8583

research/H17-Nov-2021-169160

src/H17-Nov-2021-106,327103,853

testdata/H03-May-2022-99

.cargo-checksum.jsonH A D03-May-202289 11

Cargo.lockH A D17-Nov-20213.5 KiB136119

Cargo.tomlH A D17-Nov-20212.1 KiB6758

LICENSEH A D17-Nov-20211.4 KiB137

README.mdH A D17-Nov-20217.3 KiB186133

appveyor.ymlH A D17-Nov-20211.2 KiB5248

rustfmt.tomlH A D17-Nov-202169 54

uncorrode.pyH A D17-Nov-20215.6 KiB166153

README.md

1# rust-brotli
2
3[![crates.io](http://meritbadge.herokuapp.com/brotli)](https://crates.io/crates/brotli)
4[![Build Status](https://travis-ci.org/dropbox/rust-brotli.svg?branch=master)](https://travis-ci.org/dropbox/rust-brotli)
5
6
7## What's new in 3.2
8* into_inner conversions for both Reader and Writer classes
9
10## What's new in 3.0
11* A fully compatible FFI for drop-in compatibiltiy with the https://github.com/google/brotli binaries
12  * custom allocators fully supported
13* Multithreaded compression so multiple threads can operate in unison on a single file
14* Concatenatability mode to add the feature requested in https://github.com/google/brotli/issues/628
15  * binary tool catbrotli can accomplish this if the first file was specified with -apendable and the second with -catable
16* validation mode where a file is double-checked to be able to be decompressed with the same settings; useful for benchmarking or fuzzing
17* Magic Number: where the brotli file can have a useful header with a few magic bytes, concatability info and a final output size for pre-allocating memory
18
19## What's new in 2.5
20* In 2.5 The callback also passes down an allocator to make new StaticCommands and PDFs and 256 bit floating point vectors.
21* In 2.4 The callback with the compression intermediate representation now passes a full metablock at a time. Also these items are mutable
22in case futher optimization is desired
23
24## What's new in 2.3
25
26* Flush now produces output instead of calling finish on the stream. This allows you to use the writer abstraction to
27get immediate output without having to resort to the CompressStream internal abstraction
28
29## Project Requirements
30
31Direct no-stdlib port of the C brotli compressor to Rust
32
33no dependency on the Rust stdlib: this library would be ideal for decompressing within a rust kernel among other things.
34
35This is useful to see how C and Rust compare in an apples-to-apples
36comparison where the same algorithms and data structures and
37optimizations are employed.
38
39## Compression Usage
40
41Rust brotli currently supports compression levels 0 - 11
42They should be bitwise identical to the brotli C compression engine at compression levels 0-9
43Recommended lg_window_size is between 20 and 22
44
45### With the io::Read abstraction
46```rust
47let mut input = brotli::CompressorReader::new(&mut io::stdin(), 4096 /* buffer size */,
48                                              quality as u32, lg_window_size as u32);
49```
50then you can simply read input as you would any other io::Read class
51
52### With the io::Write abstraction
53
54```rust
55let mut writer = brotli::Compressor::new(&mut io::stdout(), 4096 /* buffer size */,
56                                         quality as u32, lg_window_size as u32);
57```
58
59There are also methods to build Compressor Readers or Writers using the with_params static function
60
61eg:
62```rust
63let params = BrotliEncoderParams::default();
64// modify params to fit the application needs
65let mut writer = brotli::Compressor::with_params(&mut io::stdout(), 4096 /* buffer size */,
66                                         params);
67```
68or for the reader
69```rust
70let params = BrotliEncoderParams::default();
71// modify params to fit the application needs
72let mut writer = brotli::CompressorReader::with_params(&mut io::stdin(), 4096 /* buffer size */,
73                                                       params);
74```
75
76
77### With the Stream Copy abstraction
78
79```rust
80match brotli::BrotliCompress(&mut io::stdin(), &mut io::stdout(), &brotli_encoder_params) {
81    Ok(_) => {},
82    Err(e) => panic!("Error {:?}", e),
83}
84```
85
86## Decompression Usage
87
88### With the io::Read abstraction
89
90```rust
91let mut input = brotli::Decompressor::new(&mut io::stdin(), 4096 /* buffer size */);
92```
93then you can simply read input as you would any other io::Read class
94
95### With the io::Write abstraction
96
97```rust
98let mut writer = brotli::DecompressorWriter::new(&mut io::stdout(), 4096 /* buffer size */);
99```
100
101### With the Stream Copy abstraction
102
103```rust
104match brotli::BrotliDecompress(&mut io::stdin(), &mut io::stdout()) {
105    Ok(_) => {},
106    Err(e) => panic!("Error {:?}", e),
107}
108```
109
110### With manual memory management
111
112There are 3 steps to using brotli without stdlib
113
1141. setup the memory manager
1152. setup the BrotliState
1163. in a loop, call BrotliDecompressStream
117
118in Detail
119
120```rust
121// at global scope declare a MemPool type -- in this case we'll choose the heap to
122// avoid unsafe code, and avoid restrictions of the stack size
123
124declare_stack_allocator_struct!(MemPool, heap);
125
126// at local scope, make a heap allocated buffers to hold uint8's uint32's and huffman codes
127let mut u8_buffer = define_allocator_memory_pool!(4096, u8, [0; 32 * 1024 * 1024], heap);
128let mut u32_buffer = define_allocator_memory_pool!(4096, u32, [0; 1024 * 1024], heap);
129let mut hc_buffer = define_allocator_memory_pool!(4096, HuffmanCode, [0; 4 * 1024 * 1024], heap);
130let heap_u8_allocator = HeapPrealloc::<u8>::new_allocator(4096, &mut u8_buffer, bzero);
131let heap_u32_allocator = HeapPrealloc::<u32>::new_allocator(4096, &mut u32_buffer, bzero);
132let heap_hc_allocator = HeapPrealloc::<HuffmanCode>::new_allocator(4096, &mut hc_buffer, bzero);
133
134// At this point no more syscalls are going to be needed since everything can come from the allocators.
135
136// Feel free to activate SECCOMP jailing or other mechanisms to secure your application if you wish.
137
138// Now it's possible to setup the decompressor state
139let mut brotli_state = BrotliState::new(heap_u8_allocator, heap_u32_allocator, heap_hc_allocator);
140
141// at this point the decompressor simply needs an input and output buffer and the ability to track
142// the available data left in each buffer
143loop {
144    result = BrotliDecompressStream(&mut available_in, &mut input_offset, &input.slice(),
145                                    &mut available_out, &mut output_offset, &mut output.slice_mut(),
146                                    &mut written, &mut brotli_state);
147
148    // just end the decompression if result is BrotliResult::ResultSuccess or BrotliResult::ResultFailure
149}
150```
151
152This interface is the same interface that the C brotli decompressor uses
153
154Also feel free to use custom allocators that invoke Box directly.
155This example illustrates a mechanism to avoid subsequent syscalls after the initial allocation
156
157## Using the C interface
158
159rust-brotli is a drop-in replacement for the official http://github.com/google/brotli/ C
160implementation. That means you can use it from any place that supports that library.
161To build rust-brotli in this manner enter the c subdirectory and run make there
162
163cd c && make
164
165this should build c/target/release/libbrotli.so and should build the vanilla
166command line tool in C for compressing and decompressing any brotli file.
167
168the libbrotli.so in c/target/release should be able to replace any other libbrotli.so
169file, but with all the advantages of using safe rust (except in the FFI bindings)
170
171The code also allows a wider range of options, including forcing the prediction mode
172(eg UTF8 vs signed vs MSB vs LSB) and changing the weight of the literal cost from 540
173 to other values.
174
175Additionally the CATABLE and APPENDABLE options are exposed and allow concatenation of files
176created in this manner.
177
178Specifically CATABLE files can be concatenated in any order using the catbrotli tool
179and APPENDABLE files can be the first file in a sequence of catable files...
180eg you can combine
181appendable.br catable1.br catable2.br catable3.br
182
183or simply
184catable0.br catable1.br catable2.br catable3.br
185
186