| 3605 | } |
| 3606 | |
| 3607 | static mz_bool tdefl_compress_normal(tdefl_compressor *d) { |
| 3608 | const mz_uint8 *pSrc = d->m_pSrc; |
| 3609 | size_t src_buf_left = d->m_src_buf_left; |
| 3610 | tdefl_flush flush = d->m_flush; |
| 3611 | |
| 3612 | while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) { |
| 3613 | mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; |
| 3614 | // Update dictionary and hash chains. Keeps the lookahead size equal to |
| 3615 | // TDEFL_MAX_MATCH_LEN. |
| 3616 | if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) { |
| 3617 | mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & |
| 3618 | TDEFL_LZ_DICT_SIZE_MASK, |
| 3619 | ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; |
| 3620 | mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] |
| 3621 | << TDEFL_LZ_HASH_SHIFT) ^ |
| 3622 | d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; |
| 3623 | mz_uint num_bytes_to_process = (mz_uint)MZ_MIN( |
| 3624 | src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); |
| 3625 | const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; |
| 3626 | src_buf_left -= num_bytes_to_process; |
| 3627 | d->m_lookahead_size += num_bytes_to_process; |
| 3628 | while (pSrc != pSrc_end) { |
| 3629 | mz_uint8 c = *pSrc++; |
| 3630 | d->m_dict[dst_pos] = c; |
| 3631 | if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) |
| 3632 | d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; |
| 3633 | hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); |
| 3634 | d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; |
| 3635 | d->m_hash[hash] = (mz_uint16)(ins_pos); |
| 3636 | dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; |
| 3637 | ins_pos++; |
| 3638 | } |
| 3639 | } else { |
| 3640 | while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) { |
| 3641 | mz_uint8 c = *pSrc++; |
| 3642 | mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & |
| 3643 | TDEFL_LZ_DICT_SIZE_MASK; |
| 3644 | src_buf_left--; |
| 3645 | d->m_dict[dst_pos] = c; |
| 3646 | if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) |
| 3647 | d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; |
| 3648 | if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) { |
| 3649 | mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; |
| 3650 | mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] |
| 3651 | << (TDEFL_LZ_HASH_SHIFT * 2)) ^ |
| 3652 | (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] |
| 3653 | << TDEFL_LZ_HASH_SHIFT) ^ |
| 3654 | c) & |
| 3655 | (TDEFL_LZ_HASH_SIZE - 1); |
| 3656 | d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; |
| 3657 | d->m_hash[hash] = (mz_uint16)(ins_pos); |
| 3658 | } |
| 3659 | } |
| 3660 | } |
| 3661 | d->m_dict_size = |
| 3662 | MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); |
| 3663 | if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) |
| 3664 | break; |
no test coverage detected