1use std::marker::PhantomData;
2use std::{ptr, slice};
4
5pub use crate::tinfl::{
6 tinfl_decompress, tinfl_decompress_mem_to_heap, tinfl_decompress_mem_to_mem,
7 tinfl_decompressor, tinfl_status,
8};
9
10pub use crate::tdef::{
11 tdefl_allocate, tdefl_compress, tdefl_compress_buffer, tdefl_compress_mem_to_heap,
12 tdefl_compress_mem_to_mem, tdefl_compress_mem_to_output,
13 tdefl_create_comp_flags_from_zip_params, tdefl_deallocate, tdefl_flush, tdefl_get_adler32,
14 tdefl_get_prev_return_status, tdefl_init,
15};
16use libc::*;
17
18use crate::lib_oxide::{InternalState, StateType, StateTypeEnum, StreamOxide, MZ_ADLER32_INIT};
19
20use miniz_oxide::{mz_adler32_oxide, MZError};
21
22#[allow(bad_style)]
23mod mz_typedefs {
24 use libc::*;
25
26 pub type mz_uint32 = c_uint;
27 pub type mz_uint = c_uint;
28 pub type mz_bool = c_int;
29}
30pub use mz_typedefs::*;
31
32#[allow(bad_style)]
33#[repr(C)]
34#[derive(PartialEq, Eq)]
35pub enum CAPIReturnStatus {
36 MZ_PARAM_ERROR = -10000,
37 MZ_VERSION_ERROR = -6,
38 MZ_BUF_ERROR = -5,
39 MZ_MEM_ERROR = -4,
40 MZ_DATA_ERROR = -3,
41 MZ_STREAM_ERROR = -2,
42 MZ_ERRNO = -1,
43 MZ_OK = 0,
44 MZ_STREAM_END = 1,
45 MZ_NEED_DICT = 2,
46}
47
48#[allow(bad_style)]
50#[repr(C)]
51#[derive(PartialEq, Eq)]
52pub enum CAPIFlush {
53 MZ_NO_FLUSH = 0,
54 MZ_PARTIAL_FLUSH = 1,
55 MZ_SYNC_FLUSH = 2,
56 MZ_FULL_FLUSH = 3,
57 MZ_FINISH = 4,
58 MZ_BLOCK = 5,
59}
60
61#[allow(bad_style)]
62#[repr(C)]
63#[derive(PartialEq, Eq)]
64pub enum CAPICompressionStrategy {
65 MZ_DEFAULT_STRATEGY = 0,
66 MZ_FILTERED = 1,
67 MZ_HUFFMAN_ONLY = 2,
68 MZ_RLE = 3,
69 MZ_FIXED = 4,
70}
71
72#[allow(bad_style)]
74#[repr(C)]
75#[derive(PartialEq, Eq)]
76pub enum CAPICompressionLevel {
77 MZ_NO_COMPRESSION = 0,
78 MZ_BEST_SPEED = 1,
79 MZ_BEST_COMPRESSION = 9,
80 MZ_UBER_COMPRESSION = 10,
81 MZ_DEFAULT_LEVEL = 6,
82 MZ_DEFAULT_COMPRESSION = -1,
83}
84
85pub const MZ_CRC32_INIT: c_ulong = 0;
86
87pub fn mz_crc32_oxide(crc32: c_uint, data: &[u8]) -> c_uint {
88 let mut digest = crc32fast::Hasher::new_with_initial(crc32);
89 digest.update(data);
90 digest.finalize()
91}
92
93#[allow(bad_style)]
95pub type mz_alloc_func = unsafe extern "C" fn(*mut c_void, size_t, size_t) -> *mut c_void;
96#[allow(bad_style)]
98pub type mz_free_func = unsafe extern "C" fn(*mut c_void, *mut c_void);
99
100#[allow(bad_style)]
101pub type mz_realloc_func =
102 unsafe extern "C" fn(*mut c_void, *mut c_void, size_t, size_t) -> *mut c_void;
103
104#[allow(bad_style)]
105pub type mz_alloc_callback =
106 Option<unsafe extern "C" fn(*mut c_void, size_t, size_t) -> *mut c_void>;
107
108#[allow(bad_style)]
109pub type mz_free_callback = Option<unsafe extern "C" fn(*mut c_void, *mut c_void)>;
110
111#[repr(C)]
113#[allow(bad_style)]
114#[derive(Debug)]
115pub struct mz_stream {
116 pub next_in: *const u8,
118 pub avail_in: c_uint,
120 pub total_in: c_ulong,
122
123 pub next_out: *mut u8,
125 pub avail_out: c_uint,
127 pub total_out: c_ulong,
129
130 pub msg: *const c_char,
131 pub state: Option<Box<InternalState>>,
134
135 pub zalloc: mz_alloc_callback,
138 pub zfree: mz_free_callback,
141 pub opaque: *mut c_void,
144
145 pub data_type: StateTypeEnum,
147 pub adler: c_ulong,
149 pub reserved: c_ulong,
151}
152
153impl Default for mz_stream {
154 fn default() -> mz_stream {
155 mz_stream {
156 next_in: ptr::null(),
157 avail_in: 0,
158 total_in: 0,
159
160 next_out: ptr::null_mut(),
161 avail_out: 0,
162 total_out: 0,
163
164 msg: ptr::null(),
165 state: None,
166
167 zalloc: None,
168 zfree: None,
169 opaque: ptr::null_mut(),
170
171 data_type: StateTypeEnum::None,
172 adler: 0,
173 reserved: 0,
174 }
175 }
176}
177
178impl<'io, ST: StateType> StreamOxide<'io, ST> {
179 pub fn into_mz_stream(mut self) -> mz_stream {
180 mz_stream {
181 next_in: self
182 .next_in
183 .map_or(ptr::null(), |in_slice| in_slice.as_ptr()),
184 avail_in: self.next_in.map_or(0, |in_slice| in_slice.len() as c_uint),
185 total_in: self.total_in,
186
187 next_out: self
188 .next_out
189 .as_mut()
190 .map_or(ptr::null_mut(), |out_slice| out_slice.as_mut_ptr()),
191 avail_out: self
192 .next_out
193 .as_mut()
194 .map_or(0, |out_slice| out_slice.len() as c_uint),
195 total_out: self.total_out,
196
197 msg: ptr::null(),
198
199 zalloc: None,
200 zfree: None,
201 opaque: ptr::null_mut(),
202 state: self.state.take(),
203
204 data_type: ST::STATE_TYPE,
205 adler: self.adler as c_ulong,
206 reserved: 0,
207 }
208 }
209
210 pub unsafe fn new(stream: &mut mz_stream) -> Self {
217 Self::try_new(stream).expect(
218 "Failed to create StreamOxide, wrong state type or tried to specify allocators.",
219 )
220 }
221
222 pub unsafe fn try_new(stream: &mut mz_stream) -> Result<Self, MZError> {
229 if stream.data_type != ST::STATE_TYPE || stream.zalloc.is_some() || stream.zfree.is_some() {
231 return Err(MZError::Param);
232 }
233
234 let in_slice = stream
235 .next_in
236 .as_ref()
237 .map(|ptr| slice::from_raw_parts(ptr, stream.avail_in as usize));
238
239 let out_slice = stream
240 .next_out
241 .as_mut()
242 .map(|ptr| slice::from_raw_parts_mut(ptr, stream.avail_out as usize));
243
244 Ok(StreamOxide {
245 next_in: in_slice,
246 total_in: stream.total_in,
247 next_out: out_slice,
248 total_out: stream.total_out,
249 state: stream.state.take(),
250 adler: stream.adler as u32,
251 state_type: PhantomData,
252 })
253 }
254}
255
256unmangle!(
257 pub unsafe extern "C" fn miniz_def_alloc_func(
259 _opaque: *mut c_void,
260 items: size_t,
261 size: size_t,
262 ) -> *mut c_void {
263 libc::malloc(items * size)
264 }
265
266 pub unsafe extern "C" fn miniz_def_free_func(_opaque: *mut c_void, address: *mut c_void) {
268 libc::free(address)
269 }
270
271 pub unsafe extern "C" fn miniz_def_realloc_func(
272 _opaque: *mut c_void,
273 address: *mut c_void,
274 items: size_t,
275 size: size_t,
276 ) -> *mut c_void {
277 libc::realloc(address, items * size)
278 }
279
280 pub unsafe extern "C" fn mz_adler32(adler: c_ulong, ptr: *const u8, buf_len: usize) -> c_ulong {
285 ptr.as_ref().map_or(MZ_ADLER32_INIT as c_ulong, |r| {
286 let data = slice::from_raw_parts(r, buf_len);
287 mz_adler32_oxide(adler as u32, data) as c_ulong
288 })
289 }
290
291 pub unsafe extern "C" fn mz_crc32(crc: c_ulong, ptr: *const u8, buf_len: size_t) -> c_ulong {
296 ptr.as_ref().map_or(MZ_CRC32_INIT, |r| {
297 let data = slice::from_raw_parts(r, buf_len);
298 mz_crc32_oxide(crc as u32, data) as c_ulong
299 })
300 }
301);