diff --git a/zlib-rs/src/deflate.rs b/zlib-rs/src/deflate.rs index 22fb79b..73be115 100644 --- a/zlib-rs/src/deflate.rs +++ b/zlib-rs/src/deflate.rs @@ -29,6 +29,9 @@ mod slide_hash; mod trees_tbl; mod window; +// Position relative to the current window +pub(crate) type Pos = u16; + // SAFETY: This struct must have the same layout as [`z_stream`], so that casts and transmutations // between the two can work without UB. #[repr(C)] @@ -1229,10 +1232,10 @@ pub(crate) struct State<'a> { d_desc: TreeDesc<{ 2 * D_CODES + 1 }>, /* distance tree */ bl_desc: TreeDesc<{ 2 * BL_CODES + 1 }>, /* Huffman tree for bit lengths */ - pub(crate) prev_match: u16, /* previous match */ - pub(crate) match_available: bool, /* set if previous match exists */ pub(crate) strstart: usize, /* start of string to insert */ - pub(crate) match_start: usize, /* start of matching string */ + pub(crate) match_start: Pos, /* start of matching string */ + pub(crate) prev_match: Pos, /* previous match */ + pub(crate) match_available: bool, /* set if previous match exists */ /// Length of the best match at previous step. Matches not greater than this /// are discarded. This is used in the lazy match evaluation. @@ -1728,8 +1731,8 @@ pub(crate) fn fill_window(stream: &mut DeflateStream) { state.window.initialize_at_least(2 * wsize); state.window.filled_mut().copy_within(wsize..2 * wsize, 0); - if state.match_start >= wsize { - state.match_start -= wsize; + if state.match_start as usize >= wsize { + state.match_start -= wsize as u16; } else { state.match_start = 0; state.prev_length = 0; diff --git a/zlib-rs/src/deflate/algorithm/fast.rs b/zlib-rs/src/deflate/algorithm/fast.rs index fedb38d..22ce2f1 100644 --- a/zlib-rs/src/deflate/algorithm/fast.rs +++ b/zlib-rs/src/deflate/algorithm/fast.rs @@ -53,7 +53,7 @@ pub fn deflate_fast(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockSta // bflush = zng_tr_tally_dist(s, s->strstart - s->match_start, match_len - STD_MIN_MATCH); bflush = state.tally_dist( - state.strstart - state.match_start, + state.strstart - state.match_start as usize, match_len - STD_MIN_MATCH, ); diff --git a/zlib-rs/src/deflate/algorithm/medium.rs b/zlib-rs/src/deflate/algorithm/medium.rs index e4652a2..435c2e5 100644 --- a/zlib-rs/src/deflate/algorithm/medium.rs +++ b/zlib-rs/src/deflate/algorithm/medium.rs @@ -80,7 +80,7 @@ pub fn deflate_medium(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockS crate::deflate::longest_match::longest_match(state, hash_head); state.match_start = match_start; current_match.match_length = match_length as u16; - current_match.match_start = match_start as u16; + current_match.match_start = match_start; if (current_match.match_length as usize) < WANT_MIN_MATCH { current_match.match_length = 1; } @@ -123,7 +123,7 @@ pub fn deflate_medium(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockS crate::deflate::longest_match::longest_match(state, hash_head); state.match_start = match_start; next_match.match_length = match_length as u16; - next_match.match_start = match_start as u16; + next_match.match_start = match_start; if next_match.match_start >= next_match.strstart { /* this can happen due to some restarts */ diff --git a/zlib-rs/src/deflate/algorithm/slow.rs b/zlib-rs/src/deflate/algorithm/slow.rs index 3a0fe64..02be859 100644 --- a/zlib-rs/src/deflate/algorithm/slow.rs +++ b/zlib-rs/src/deflate/algorithm/slow.rs @@ -49,7 +49,7 @@ pub fn deflate_slow(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockSta }; // Find the longest match, discarding those <= prev_length. - state.prev_match = state.match_start as u16; + state.prev_match = state.match_start; match_len = STD_MIN_MATCH - 1; dist = state.strstart as isize - hash_head as isize; diff --git a/zlib-rs/src/deflate/longest_match.rs b/zlib-rs/src/deflate/longest_match.rs index 28d57eb..b60b428 100644 --- a/zlib-rs/src/deflate/longest_match.rs +++ b/zlib-rs/src/deflate/longest_match.rs @@ -1,6 +1,4 @@ -use crate::deflate::{State, MIN_LOOKAHEAD, STD_MAX_MATCH, STD_MIN_MATCH}; - -type Pos = u16; +use crate::deflate::{Pos, State, MIN_LOOKAHEAD, STD_MAX_MATCH, STD_MIN_MATCH}; const EARLY_EXIT_TRIGGER_LEVEL: i8 = 5; @@ -20,18 +18,20 @@ const UNALIGNED64_OK: bool = cfg!(any( target_arch = "powerpc64", )); -pub fn longest_match(state: &crate::deflate::State, cur_match: u16) -> (usize, usize) { +/// Find the (length, offset) in the window of the longest match for the string +/// at offset cur_match +pub fn longest_match(state: &crate::deflate::State, cur_match: u16) -> (usize, u16) { longest_match_help::(state, cur_match) } -pub fn longest_match_slow(state: &crate::deflate::State, cur_match: u16) -> (usize, usize) { +pub fn longest_match_slow(state: &crate::deflate::State, cur_match: u16) -> (usize, u16) { longest_match_help::(state, cur_match) } fn longest_match_help( state: &crate::deflate::State, mut cur_match: u16, -) -> (usize, usize) { +) -> (usize, u16) { let mut match_start = state.match_start; let strstart = state.strstart; @@ -270,7 +270,7 @@ fn longest_match_help( ); if len > best_len { - match_start = (cur_match - match_offset) as usize; + match_start = cur_match - match_offset; /* Do not look for matches beyond the end of the input. */ if len > lookahead { @@ -298,7 +298,7 @@ fn longest_match_help( } // Look for a better string offset - if SLOW && len > STD_MIN_MATCH && match_start + len < strstart { + if SLOW && len > STD_MIN_MATCH && match_start as usize + len < strstart { let mut pos: Pos; // uint32_t i, hash; // unsigned char *scan_endstr; @@ -365,6 +365,6 @@ fn longest_match_help( (best_len, match_start) } -fn break_matching(state: &State, best_len: usize, match_start: usize) -> (usize, usize) { +fn break_matching(state: &State, best_len: usize, match_start: u16) -> (usize, u16) { (Ord::min(best_len, state.lookahead), match_start) }