summaryrefslogtreecommitdiff
path: root/neozip/deflate_fast.c
diff options
context:
space:
mode:
authorMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 19:56:09 +0300
committerMehmet Samet Duman <yongdohyun@projecttick.org>2026-04-02 19:56:09 +0300
commit7fb132859fda54aa96bc9dd46d302b343eeb5a02 (patch)
treeb43ae77d7451fb470a260c03349a1caf2846c5e5 /neozip/deflate_fast.c
parentb1e34e861b5d732afe828d58aad2c638135061fd (diff)
parentc2712b8a345191f6ed79558c089777df94590087 (diff)
downloadProject-Tick-7fb132859fda54aa96bc9dd46d302b343eeb5a02.tar.gz
Project-Tick-7fb132859fda54aa96bc9dd46d302b343eeb5a02.zip
Add 'neozip/' from commit 'c2712b8a345191f6ed79558c089777df94590087'
git-subtree-dir: neozip git-subtree-mainline: b1e34e861b5d732afe828d58aad2c638135061fd git-subtree-split: c2712b8a345191f6ed79558c089777df94590087
Diffstat (limited to 'neozip/deflate_fast.c')
-rw-r--r--neozip/deflate_fast.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/neozip/deflate_fast.c b/neozip/deflate_fast.c
new file mode 100644
index 0000000000..adf0113c29
--- /dev/null
+++ b/neozip/deflate_fast.c
@@ -0,0 +1,112 @@
+/* deflate_fast.c -- compress data using the fast strategy of deflation algorithm
+ *
+ * Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zbuild.h"
+#include "zmemory.h"
+#include "deflate.h"
+#include "deflate_p.h"
+#include "functable.h"
+#include "insert_string_p.h"
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+Z_INTERNAL block_state deflate_fast(deflate_state *s, int flush) {
+ unsigned char *window = s->window;
+ int bflush = 0; /* set if current block must be flushed */
+ uint32_t match_len = 0;
+
+ for (;;) {
+ uint8_t lc;
+
+ /* 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 (s->lookahead < MIN_LOOKAHEAD) {
+ PREFIX(fill_window)(s);
+ if (UNLIKELY(s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH)) {
+ return need_more;
+ }
+ if (UNLIKELY(s->lookahead == 0))
+ break; /* flush the current block */
+ }
+
+ /* Insert the string window[strstart .. strstart+2] in the
+ * dictionary, and set hash_head to the head of the hash chain:
+ */
+ if (s->lookahead >= WANT_MIN_MATCH) {
+ uint32_t str_val = Z_U32_FROM_LE(zng_memread_4(window + s->strstart));
+ uint32_t hash_head = quick_insert_value(s, s->strstart, str_val);
+ int64_t dist = (int64_t)s->strstart - hash_head;
+ lc = (uint8_t)str_val;
+
+ /* Find the longest match, discarding those <= prev_length.
+ * At this point we have always match length < WANT_MIN_MATCH
+ */
+ if (dist <= MAX_DIST(s) && 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).
+ */
+ match_len = FUNCTABLE_CALL(longest_match)(s, (uint32_t)hash_head);
+ /* longest_match() sets match_start */
+ }
+ } else {
+ lc = window[s->strstart];
+ }
+
+ if (match_len >= WANT_MIN_MATCH) {
+ Assert(s->strstart <= UINT16_MAX, "strstart should fit in uint16_t");
+ Assert(s->match_start <= UINT16_MAX, "match_start should fit in uint16_t");
+ check_match(s, s->strstart, s->match_start, match_len);
+
+ bflush = zng_tr_tally_dist(s, s->strstart - s->match_start, match_len - STD_MIN_MATCH);
+
+ s->lookahead -= match_len;
+
+ /* Insert new strings in the hash table only if the match length
+ * is not too large. This saves time but degrades compression.
+ */
+ if (match_len <= s->max_insert_length && s->lookahead >= WANT_MIN_MATCH) {
+ match_len--; /* string at strstart already in table */
+ s->strstart++;
+
+ insert_string_static(s, s->strstart, match_len);
+ s->strstart += match_len;
+ } else {
+ s->strstart += match_len;
+ quick_insert_string(s, s->strstart + 2 - STD_MIN_MATCH);
+
+ /* If lookahead < STD_MIN_MATCH, ins_h is garbage, but it does not
+ * matter since it will be recomputed at next deflate call.
+ */
+ }
+ match_len = 0;
+ } else {
+ /* No match, output a literal byte */
+ bflush = zng_tr_tally_lit(s, lc);
+ s->lookahead--;
+ s->strstart++;
+ }
+ if (UNLIKELY(bflush))
+ FLUSH_BLOCK(s, 0);
+ }
+ s->insert = s->strstart < (STD_MIN_MATCH - 1) ? s->strstart : (STD_MIN_MATCH - 1);
+
+ if (UNLIKELY(flush == Z_FINISH)) {
+ FLUSH_BLOCK(s, 1);
+ return finish_done;
+ }
+ if (UNLIKELY(s->sym_next))
+ FLUSH_BLOCK(s, 0);
+ return block_done;
+}