miniz_oxide/
lib.rs

1//! A pure rust replacement for the [miniz](https://github.com/richgel999/miniz)
2//! DEFLATE/zlib encoder/decoder.
3//! Used a rust back-end for the
4//! [flate2](https://github.com/alexcrichton/flate2-rs) crate.
5//!
6#![cfg_attr(
7    feature = "with-alloc",
8    doc = r##"
9# Usage
10## Simple compression/decompression:
11``` rust
12
13use miniz_oxide::inflate::decompress_to_vec;
14use miniz_oxide::deflate::compress_to_vec;
15
16fn roundtrip(data: &[u8]) {
17    let compressed = compress_to_vec(data, 6);
18    let decompressed = decompress_to_vec(compressed.as_slice()).expect("Failed to decompress!");
19#   let _ = decompressed;
20}
21
22# roundtrip(b"Test_data test data lalalal blabla");
23"##
24)]
25#![forbid(unsafe_code)]
26#![cfg_attr(not(feature = "std"), no_std)]
27
28#[cfg(feature = "with-alloc")]
29extern crate alloc;
30
31#[cfg(feature = "with-alloc")]
32pub mod deflate;
33pub mod inflate;
34mod shared;
35
36pub use crate::shared::update_adler32 as mz_adler32_oxide;
37pub use crate::shared::{MZ_ADLER32_INIT, MZ_DEFAULT_WINDOW_BITS};
38
39/// A list of flush types.
40///
41/// See <http://www.bolet.org/~pornin/deflate-flush.html> for more in-depth info.
42#[repr(i32)]
43#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
44pub enum MZFlush {
45    /// Don't force any flushing.
46    /// Used when more input data is expected.
47    None = 0,
48    /// Zlib partial flush.
49    /// Currently treated as [`Sync`].
50    Partial = 1,
51    /// Finish compressing the currently buffered data, and output an empty raw block.
52    /// Has no use in decompression.
53    Sync = 2,
54    /// Same as [`Sync`], but resets the compression dictionary so that further compressed
55    /// data does not depend on data compressed before the flush.
56    ///
57    /// Has no use in decompression, and is an error to supply in that case.
58    Full = 3,
59    /// Attempt to flush the remaining data and end the stream.
60    Finish = 4,
61    /// Not implemented.
62    Block = 5,
63}
64
65impl MZFlush {
66    /// Create an MZFlush value from an integer value.
67    ///
68    /// Returns `MZError::Param` on invalid values.
69    pub fn new(flush: i32) -> Result<Self, MZError> {
70        match flush {
71            0 => Ok(MZFlush::None),
72            1 | 2 => Ok(MZFlush::Sync),
73            3 => Ok(MZFlush::Full),
74            4 => Ok(MZFlush::Finish),
75            _ => Err(MZError::Param),
76        }
77    }
78}
79
80/// A list of miniz successful status codes.
81///
82/// These are emitted as the [`Ok`] side of a [`MZResult`] in the [`StreamResult`] returned from
83/// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`].
84#[repr(i32)]
85#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
86pub enum MZStatus {
87    /// Operation succeeded.
88    ///
89    /// Some data was decompressed or compressed; see the byte counters in the [`StreamResult`] for
90    /// details.
91    Ok = 0,
92
93    /// Operation succeeded and end of deflate stream was found.
94    ///
95    /// X-ref [`TINFLStatus::Done`][inflate::TINFLStatus::Done] or
96    /// [`TDEFLStatus::Done`][deflate::core::TDEFLStatus::Done] for `inflate` or `deflate`
97    /// respectively.
98    StreamEnd = 1,
99
100    /// Unused
101    NeedDict = 2,
102}
103
104/// A list of miniz failed status codes.
105///
106/// These are emitted as the [`Err`] side of a [`MZResult`] in the [`StreamResult`] returned from
107/// [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`].
108#[repr(i32)]
109#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
110pub enum MZError {
111    /// Unused
112    ErrNo = -1,
113
114    /// General stream error.
115    ///
116    /// See [`inflate::stream::inflate()`] docs for details of how it can occur there.
117    ///
118    /// See [`deflate::stream::deflate()`] docs for how it can in principle occur there, though it's
119    /// believed impossible in practice.
120    Stream = -2,
121
122    /// Error in inflation; see [`inflate::stream::inflate()`] for details.
123    ///
124    /// Not returned from [`deflate::stream::deflate()`].
125    Data = -3,
126
127    /// Unused
128    Mem = -4,
129
130    /// Buffer-related error.
131    ///
132    /// See the docs of [`deflate::stream::deflate()`] or [`inflate::stream::inflate()`] for details
133    /// of when it would trigger in the one you're using.
134    Buf = -5,
135
136    /// Unused
137    Version = -6,
138
139    /// Bad parameters.
140    ///
141    /// This can be returned from [`deflate::stream::deflate()`] in the case of bad parameters.  See
142    /// [`TDEFLStatus::BadParam`][deflate::core::TDEFLStatus::BadParam].
143    Param = -10_000,
144}
145
146/// How compressed data is wrapped.
147#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
148#[non_exhaustive]
149pub enum DataFormat {
150    /// Wrapped using the [zlib](http://www.zlib.org/rfc-zlib.html) format.
151    Zlib,
152    /// Zlib wrapped but ignore and don't compute the adler32 checksum.
153    /// Currently only used for inflate, behaves the same as Zlib for compression.
154    ZLibIgnoreChecksum,
155    /// Raw DEFLATE.
156    Raw,
157}
158
159impl DataFormat {
160    pub fn from_window_bits(window_bits: i32) -> DataFormat {
161        if window_bits > 0 {
162            DataFormat::Zlib
163        } else {
164            DataFormat::Raw
165        }
166    }
167
168    pub fn to_window_bits(self) -> i32 {
169        match self {
170            DataFormat::Zlib | DataFormat::ZLibIgnoreChecksum => shared::MZ_DEFAULT_WINDOW_BITS,
171            DataFormat::Raw => -shared::MZ_DEFAULT_WINDOW_BITS,
172        }
173    }
174}
175
176/// `Result` alias for all miniz status codes both successful and failed.
177pub type MZResult = Result<MZStatus, MZError>;
178
179/// A structure containing the result of a call to the inflate or deflate streaming functions.
180#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
181pub struct StreamResult {
182    /// The number of bytes consumed from the input slice.
183    pub bytes_consumed: usize,
184    /// The number of bytes written to the output slice.
185    pub bytes_written: usize,
186    /// The return status of the call.
187    pub status: MZResult,
188}
189
190impl StreamResult {
191    #[inline]
192    pub const fn error(error: MZError) -> StreamResult {
193        StreamResult {
194            bytes_consumed: 0,
195            bytes_written: 0,
196            status: Err(error),
197        }
198    }
199}
200
201impl core::convert::From<StreamResult> for MZResult {
202    fn from(res: StreamResult) -> Self {
203        res.status
204    }
205}
206
207impl core::convert::From<&StreamResult> for MZResult {
208    fn from(res: &StreamResult) -> Self {
209        res.status
210    }
211}