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