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