MCPcopy Create free account
hub / github.com/InteractiveComputerGraphics/SPlisHSPlasH / deflate_slow

Function deflate_slow

extern/zlib/src/deflate.c:1910–2030  ·  view source on GitHub ↗

=========================================================================== * Same as above, but achieves better compression. We use a lazy * evaluation for matches: a match is finally adopted only if there is * no better match at the next window position. */

Source from the content-addressed store, hash-verified

1908 * no better match at the next window position.
1909 */
1910local block_state deflate_slow(deflate_state *s, int flush) {
1911 IPos hash_head; /* head of hash chain */
1912 int bflush; /* set if current block must be flushed */
1913
1914 /* Process the input block. */
1915 for (;;) {
1916 /* Make sure that we always have enough lookahead, except
1917 * at the end of the input file. We need MAX_MATCH bytes
1918 * for the next match, plus MIN_MATCH bytes to insert the
1919 * string following the next match.
1920 */
1921 if (s->lookahead < MIN_LOOKAHEAD) {
1922 fill_window(s);
1923 if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
1924 return need_more;
1925 }
1926 if (s->lookahead == 0) break; /* flush the current block */
1927 }
1928
1929 /* Insert the string window[strstart .. strstart + 2] in the
1930 * dictionary, and set hash_head to the head of the hash chain:
1931 */
1932 hash_head = NIL;
1933 if (s->lookahead >= MIN_MATCH) {
1934 INSERT_STRING(s, s->strstart, hash_head);
1935 }
1936
1937 /* Find the longest match, discarding those <= prev_length.
1938 */
1939 s->prev_length = s->match_length, s->prev_match = s->match_start;
1940 s->match_length = MIN_MATCH-1;
1941
1942 if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
1943 s->strstart - hash_head <= MAX_DIST(s)) {
1944 /* To simplify the code, we prevent matches with the string
1945 * of window index 0 (in particular we have to avoid a match
1946 * of the string with itself at the start of the input file).
1947 */
1948 s->match_length = longest_match (s, hash_head);
1949 /* longest_match() sets match_start */
1950
1951 if (s->match_length <= 5 && (s->strategy == Z_FILTERED
1952#if TOO_FAR <= 32767
1953 || (s->match_length == MIN_MATCH &&
1954 s->strstart - s->match_start > TOO_FAR)
1955#endif
1956 )) {
1957
1958 /* If prev_match is also MIN_MATCH, match_start is garbage
1959 * but we will ignore the current match anyway.
1960 */
1961 s->match_length = MIN_MATCH-1;
1962 }
1963 }
1964 /* If there was a match at the previous step and the current
1965 * match is not better, output the previous match:
1966 */
1967 if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {

Callers

nothing calls this directly

Calls 3

fill_windowFunction · 0.85
longest_matchFunction · 0.85
check_matchFunction · 0.85

Tested by

no test coverage detected