pubfn deflate_fast(stream: &mut DeflateStream, flush: DeflateFlush) -> BlockState { loop { // Make sure that we always have enough lookahead, except // at the end of the input file. We need STD_MAX_MATCH bytes // for the next match, plus WANT_MIN_MATCH bytes to insert the // string following the next match. if stream.state.lookahead < MIN_LOOKAHEAD {
fill_window(stream); if stream.state.lookahead < MIN_LOOKAHEAD && flush == DeflateFlush::NoFlush { return BlockState::NeedMore;
} if stream.state.lookahead == 0 { break; /* flush the current block */
}
}
let state = &mut stream.state;
// Insert the string window[strstart .. strstart+2] in the // dictionary, and set hash_head to the head of the hash chain:
let lc: u8; // Literal character to output if there is no match. if state.lookahead >= WANT_MIN_MATCH { let val = u32::from_le_bytes(
state.window.filled()[state.strstart..state.strstart + 4]
.try_into()
.unwrap(),
); let hash_head = StandardHashCalc::quick_insert_value(state, state.strstart, val); let dist = state.strstart as isize - hash_head as isize;
// Find the longest match for the string starting at offset state.strstart. if dist <= state.max_dist() as isize && dist > 0 && hash_head != 0 { // To simplify the code, we prevent matches with the string // of window index 0 (in particular we have to avoid a match // of the string with itself at the start of the input file). letmut match_len;
(match_len, state.match_start) = crate::deflate::longest_match::longest_match(state, hash_head); if match_len >= WANT_MIN_MATCH { let bflush = state.tally_dist(
state.strstart - state.match_start as usize,
match_len - STD_MIN_MATCH,
);
state.lookahead -= match_len;
/* Insert new strings in the hash table only if the match length *isnottoolarge.Thissavestimebutdegradescompression.
*/ if match_len <= state.max_insert_length() && state.lookahead >= WANT_MIN_MATCH {
match_len -= 1; /* string at strstart already in table */
state.strstart += 1;
/* If lookahead < STD_MIN_MATCH, ins_h is garbage, but it does not *mattersinceitwillberecomputedatnextdeflatecall.
*/
} if bflush {
flush_block!(stream, false);
} continue;
}
}
lc = val as u8;
} else {
lc = state.window.filled()[state.strstart];
} /* No match, output a literal byte */ let bflush = state.tally_lit(lc);
state.lookahead -= 1;
state.strstart += 1; if bflush {
flush_block!(stream, false);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.