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