Expand description
This crate is a C API for zlib-rs. The API is broadly equivalent to zlib-sys
and zlib-ng-sys
, but does not currently provide the gz*
family of functions.
From a rust perspective, this API is not very ergonomic. Use the flate2
crate for a more
ergonomic rust interface to zlib.
§Features
custom-prefix
Add a custom prefix to all exported symbols.
The value of the LIBZ_RS_SYS_PREFIX
is used as a prefix for all exported symbols. For example:
> LIBZ_RS_SYS_PREFIX="MY_CUSTOM_PREFIX" cargo build -p libz-rs-sys --features=custom-prefix
Compiling libz-rs-sys v0.2.1 (/home/folkertdev/rust/zlib-rs/libz-rs-sys)
Finished `dev` profile [optimized + debuginfo] target(s) in 0.21s
> objdump -tT target/debug/liblibz_rs_sys.so | grep "uncompress"
0000000000081028 l O .got 0000000000000000 _ZN7zlib_rs7inflate10uncompress17he7d985e55c58a189E$got
000000000002c570 l F .text 00000000000001ef _ZN7zlib_rs7inflate10uncompress17he7d985e55c58a189E
0000000000024330 g F .text 000000000000008e MY_CUSTOM_PREFIXuncompress
0000000000024330 g DF .text 000000000000008e Base MY_CUSTOM_PREFIXuncompress
c-allocator
, rust-allocator
Pick the default allocator implementation that is used if no zalloc
and zfree
are configured in the input z_stream
.
c-allocator
: usemalloc
/free
for the implementation ofzalloc
andzfree
rust-allocator
: the rust global allocator for the implementation ofzalloc
andzfree
The rust-allocator
is the default when this crate is used as a rust dependency, and slightly more efficient because alignment is handled by the allocator. When building a dynamic library, it may make sense to use c-allocator
instead.
std
Assume that std
is available. When this feature is turned off, this crate is compatible with #![no_std]
.
§Example
This example compresses (“deflates”) the string "Hello, World!"
and then decompresses
(“inflates”) it again.
let mut strm = libz_rs_sys::z_stream::default();
let version = libz_rs_sys::zlibVersion();
let stream_size = core::mem::size_of_val(&strm) as i32;
let level = 6; // the default compression level
let err = unsafe { libz_rs_sys::deflateInit_(&mut strm, level, version, stream_size) };
assert_eq!(err, libz_rs_sys::Z_OK);
let input = "Hello, World!";
strm.avail_in = input.len() as _;
strm.next_in = input.as_ptr();
let mut output = [0u8; 32];
strm.avail_out = output.len() as _;
strm.next_out = output.as_mut_ptr();
let err = unsafe { libz_rs_sys::deflate(&mut strm, libz_rs_sys::Z_FINISH) };
assert_eq!(err, libz_rs_sys::Z_STREAM_END);
let err = unsafe { libz_rs_sys::deflateEnd(&mut strm) };
assert_eq!(err, libz_rs_sys::Z_OK);
let deflated = &mut output[..strm.total_out as usize];
let mut strm = libz_rs_sys::z_stream::default();
let err = unsafe { libz_rs_sys::inflateInit_(&mut strm, version, stream_size) };
assert_eq!(err, libz_rs_sys::Z_OK);
strm.avail_in = deflated.len() as _;
strm.next_in = deflated.as_ptr();
let mut output = [0u8; 32];
strm.avail_out = output.len() as _;
strm.next_out = output.as_mut_ptr();
let err = unsafe { libz_rs_sys::inflate(&mut strm, libz_rs_sys::Z_FINISH) };
assert_eq!(err, libz_rs_sys::Z_STREAM_END);
let err = unsafe { libz_rs_sys::inflateEnd(&mut strm) };
assert_eq!(err, libz_rs_sys::Z_OK);
let inflated = &output[..strm.total_out as usize];
assert_eq!(inflated, input.as_bytes())
§Compression Levels
The zlib library supports compression levels 0 up to and including 9. The level indicates a tradeoff between time spent on the compression versus the compression ratio, the factor by which the input is reduced in size:
- level 0: no compression at all
- level 1: fastest compression
- level 6: default (a good tradeoff between speed and compression ratio)
- level 9: best compression
Beyond this intuition, the exact behavior of the compression levels is not specified. The implementation of zlib-rs
follows the implementation of zlig-ng
, and deviates from the one in stock zlib.
In particular, our compression level 1 is extremely fast, but also just does not compress that well. On the silesia-small.tar
input file, we see these output sizes:
implementation | compression level | output size (mb) |
---|---|---|
- | 0 | 15.74 |
stock | 1 | 7.05 |
rs | 1 | 8.52 |
rs | 2 | 6.90 |
rs | 4 | 6.55 |
But, zlib-rs
is much faster than stock zlib. In our benchmarks, it is only at level 4 that we spend roughly as much time as stock zlib on level 1:
implementation | compression level | wall time (ms) |
---|---|---|
stock | 1 | 185 |
rs | 2 | 139 |
rs | 4 | 181 |
In our example, the main options are:
- level 1: worse compression, but much faster
- level 2: equivalent compression, but significantly faster
- level 4: better compression, at the same speed
In summary, when you upgrade from stock zlib, we recommend that you benchmark on your data and target platform, and pick the right compression level for your use case.
§Safety
Most of the functions in this module are unsafe fn
s, meaning that their behavior may be
undefined if certain assumptions are broken by the caller. In most cases, documentation
in this module refers to the safety assumptions of standard library functions.
In most cases, pointers must be either NULL
or satisfy the requirements of &*ptr
or &mut *ptr
. This requirement maps to the requirements of pointer::as_ref
and pointer::as_mut
for immutable and mutable pointers respectively.
For pointer and length pairs, describing some sequence of elements in memory, the requirements
of core::slice::from_raw_parts
or core::slice::from_raw_parts_mut
apply. In some cases,
the element type T
is converted into MaybeUninit<T>
, meaning that while the slice must be
valid, the elements in the slice can be uninitialized. Using uninitialized buffers for output
is more performant.
Finally, some functions accept a string argument, which must either be NULL
or satisfy the
requirements of core::ffi::CStr::from_ptr
.
Structs§
- gz_
header - gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields.
- z_
stream
Enums§
Constants§
- Z_ASCII
- Z_
BEST_ COMPRESSION - Z_
BEST_ SPEED - Z_
BINARY - Z_BLOCK
- Z_
BUF_ ERROR - Z_
DATA_ ERROR - Z_
DEFAULT_ COMPRESSION - Z_
DEFAULT_ STRATEGY - Z_
DEFLATED - Z_ERRNO
- Z_
FILTERED - Z_
FINISH - Z_FIXED
- Z_
FULL_ FLUSH - Z_
HUFFMAN_ ONLY - Z_
MEM_ ERROR - Z_
NEED_ DICT - Z_
NO_ COMPRESSION - Z_
NO_ FLUSH - Z_OK
- Z_
PARTIAL_ FLUSH - Z_RLE
- Z_
STREAM_ END - Z_
STREAM_ ERROR - Z_
SYNC_ FLUSH - Z_TEXT
- Z_TREES
- Z_
UNKNOWN - Z_
VERSION_ ERROR
Functions§
- adler32⚠
- Calculates the adler32 checksum of a sequence of bytes.
- adler32_
combine - Combines the checksum of two slices into one.
- compress⚠
- Compresses
source
intodest
, and writes the final deflated size intodestLen
. - compress2⚠
- Compresses
source
intodest
, and writes the final deflated size intodestLen
. - compress
Bound - Returns an upper bound on the compressed size after
compress
orcompress2
onsourceLen
bytes. - crc32⚠
- Calculates the crc32 checksum of a sequence of bytes.
- crc32_
combine - Combines the checksum of two slices into one.
- deflate⚠
- Compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full.
- deflate
Bound ⚠ - Returns an upper bound on the compressed size after deflation of
sourceLen
bytes. - deflate
Copy ⚠ - Sets the destination stream as a complete copy of the source stream.
- deflate
End ⚠ - Deallocates all dynamically allocated data structures for this stream.
- deflate
Init2_ ⚠ - Initializes the state for compression
- deflate
Init_ ⚠ - Initializes the state for compression
- deflate
Params ⚠ - Dynamically update the compression level and compression strategy.
- deflate
Pending ⚠ - Returns the number of bytes and bits of output that have been generated, but not yet provided in the available output.
- deflate
Prime ⚠ - Inserts bits in the deflate output stream.
- deflate
Reset ⚠ - This function is equivalent to
deflateEnd
followed bydeflateInit_
, but does not free and reallocate the internal compression state. - deflate
SetDictionary ⚠ - Initializes the compression dictionary from the given byte sequence without producing any compressed output.
- deflate
SetHeader ⚠ - Provides gzip header information for when a gzip stream is requested by
deflateInit2_
. - deflate
Tune ⚠ - Fine tune deflate’s internal compression parameters.
- inflate⚠
- Decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full.
- inflate
Back ⚠ - Decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full.
- inflate
Back ⚠End - Deallocates all dynamically allocated data structures for this stream.
- inflate
Back ⚠Init_ - Initializes the state for decompression
- inflate
Copy ⚠ - Sets the destination stream as a complete copy of the source stream.
- inflate
End ⚠ - Deallocates all dynamically allocated data structures for this stream.
- inflate
GetHeader ⚠ - Requests that gzip header information be stored in the provided
gz_header
structure. - inflate
Init2_ ⚠ - Initializes the state for decompression
- inflate
Init_ ⚠ - Initializes the state for decompression
- inflate
Mark ⚠ - Gives information about the current location of the input stream.
- inflate
Prime ⚠ - Inserts bits in the inflate input stream.
- inflate
Reset ⚠ - Equivalent to
inflateEnd
followed byinflateInit_
, but does not free and reallocate the internal decompression state. - inflate
Reset2 ⚠ - This function is the same as
inflateReset
, but it also permits changing the wrap and window size requests. - inflate
SetDictionary ⚠ - Initializes the decompression dictionary from the given uncompressed byte sequence.
- inflate
Sync ⚠ - Skips invalid compressed data until
- uncompress⚠
- Inflates
source
intodest
, and writes the final inflated size intodestLen
. - zError
- Get the error message for an error. This could be the value returned by e.g.
compress
orinflate
. - zlib
Version - The version of the zlib library.