< prev index next >

src/java.base/share/native/libzip/zlib/trees.c

Print this page
@@ -21,11 +21,11 @@
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  /* trees.c -- output deflated data using Huffman coding
-  * Copyright (C) 1995-2021 Jean-loup Gailly
+  * Copyright (C) 1995-2024 Jean-loup Gailly
   * detect_data_type() function provided freely by Cosmin Truta, 2006
   * For conditions of distribution and use, see copyright notice in zlib.h
   */
  
  /*

@@ -144,43 +144,120 @@
      int     extra_base;          /* base index for extra_bits */
      int     elems;               /* max number of elements in the tree */
      int     max_length;          /* max bit length for the codes */
  };
  
- local const static_tree_desc  static_l_desc =
+ #ifdef NO_INIT_GLOBAL_POINTERS
+ #  define TCONST
+ #else
+ #  define TCONST const
+ #endif
+ 
+ local TCONST static_tree_desc static_l_desc =
  {static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
  
- local const static_tree_desc  static_d_desc =
+ local TCONST static_tree_desc static_d_desc =
  {static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
  
- local const static_tree_desc  static_bl_desc =
+ local TCONST static_tree_desc static_bl_desc =
  {(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
  
  /* ===========================================================================
-  * Local (static) routines in this file.
+  * Output a short LSB first on the stream.
+  * IN assertion: there is enough room in pendingBuf.
+  */
+ #define put_short(s, w) { \
+     put_byte(s, (uch)((w) & 0xff)); \
+     put_byte(s, (uch)((ush)(w) >> 8)); \
+ }
+ 
+ /* ===========================================================================
+  * Reverse the first len bits of a code, using straightforward code (a faster
+  * method would use a table)
+  * IN assertion: 1 <= len <= 15
   */
+ local unsigned bi_reverse(unsigned code, int len) {
+     register unsigned res = 0;
+     do {
+         res |= code & 1;
+         code >>= 1, res <<= 1;
+     } while (--len > 0);
+     return res >> 1;
+ }
  
- local void tr_static_init OF((void));
- local void init_block     OF((deflate_state *s));
- local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
- local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
- local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
- local void build_tree     OF((deflate_state *s, tree_desc *desc));
- local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
- local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
- local int  build_bl_tree  OF((deflate_state *s));
- local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
-                               int blcodes));
- local void compress_block OF((deflate_state *s, const ct_data *ltree,
-                               const ct_data *dtree));
- local int  detect_data_type OF((deflate_state *s));
- local unsigned bi_reverse OF((unsigned code, int len));
- local void bi_windup      OF((deflate_state *s));
- local void bi_flush       OF((deflate_state *s));
+ /* ===========================================================================
+  * Flush the bit buffer, keeping at most 7 bits in it.
+  */
+ local void bi_flush(deflate_state *s) {
+     if (s->bi_valid == 16) {
+         put_short(s, s->bi_buf);
+         s->bi_buf = 0;
+         s->bi_valid = 0;
+     } else if (s->bi_valid >= 8) {
+         put_byte(s, (Byte)s->bi_buf);
+         s->bi_buf >>= 8;
+         s->bi_valid -= 8;
+     }
+ }
+ 
+ /* ===========================================================================
+  * Flush the bit buffer and align the output on a byte boundary
+  */
+ local void bi_windup(deflate_state *s) {
+     if (s->bi_valid > 8) {
+         put_short(s, s->bi_buf);
+     } else if (s->bi_valid > 0) {
+         put_byte(s, (Byte)s->bi_buf);
+     }
+     s->bi_buf = 0;
+     s->bi_valid = 0;
+ #ifdef ZLIB_DEBUG
+     s->bits_sent = (s->bits_sent + 7) & ~7;
+ #endif
+ }
+ 
+ /* ===========================================================================
+  * Generate the codes for a given tree and bit counts (which need not be
+  * optimal).
+  * IN assertion: the array bl_count contains the bit length statistics for
+  * the given tree and the field len is set for all tree elements.
+  * OUT assertion: the field code is set for all tree elements of non
+  *     zero code length.
+  */
+ local void gen_codes(ct_data *tree, int max_code, ushf *bl_count) {
+     ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+     unsigned code = 0;         /* running code value */
+     int bits;                  /* bit index */
+     int n;                     /* code index */
+ 
+     /* The distribution counts are first used to generate the code values
+      * without bit reversal.
+      */
+     for (bits = 1; bits <= MAX_BITS; bits++) {
+         code = (code + bl_count[bits - 1]) << 1;
+         next_code[bits] = (ush)code;
+     }
+     /* Check that the bit counts in bl_count are consistent. The last code
+      * must be all ones.
+      */
+     Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
+             "inconsistent bit counts");
+     Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+ 
+     for (n = 0;  n <= max_code; n++) {
+         int len = tree[n].Len;
+         if (len == 0) continue;
+         /* Now reverse the bits */
+         tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
+ 
+         Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
+     }
+ }
  
  #ifdef GEN_TREES_H
- local void gen_trees_header OF((void));
+ local void gen_trees_header(void);
  #endif
  
  #ifndef ZLIB_DEBUG
  #  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
     /* Send a code of the given tree. c and tree must not have side effects */

@@ -189,31 +266,16 @@
  #  define send_code(s, c, tree) \
       { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
         send_bits(s, tree[c].Code, tree[c].Len); }
  #endif
  
- /* ===========================================================================
-  * Output a short LSB first on the stream.
-  * IN assertion: there is enough room in pendingBuf.
-  */
- #define put_short(s, w) { \
-     put_byte(s, (uch)((w) & 0xff)); \
-     put_byte(s, (uch)((ush)(w) >> 8)); \
- }
- 
  /* ===========================================================================
   * Send a value on a given number of bits.
   * IN assertion: length <= 16 and value fits in length bits.
   */
  #ifdef ZLIB_DEBUG
- local void send_bits      OF((deflate_state *s, int value, int length));
- 
- local void send_bits(s, value, length)
-     deflate_state *s;
-     int value;  /* value to send */
-     int length; /* number of bits */
- {
+ local void send_bits(deflate_state *s, int value, int length) {
      Tracevv((stderr," l %2d v %4x ", length, value));
      Assert(length > 0 && length <= 15, "invalid length");
      s->bits_sent += (ulg)length;
  
      /* If not enough room in bi_buf, use (valid) bits from bi_buf and

@@ -251,12 +313,11 @@
  /* the arguments must not have side effects */
  
  /* ===========================================================================
   * Initialize the various 'constant' tables.
   */
- local void tr_static_init()
- {
+ local void tr_static_init(void) {
  #if defined(GEN_TREES_H) || !defined(STDC)
      static int static_init_done = 0;
      int n;        /* iterates over tree elements */
      int bits;     /* bit counter */
      int length;   /* length value */

@@ -345,12 +406,11 @@
  
  #  define SEPARATOR(i, last, width) \
        ((i) == (last)? "\n};\n\n" :    \
         ((i) % (width) == (width) - 1 ? ",\n" : ", "))
  
- void gen_trees_header()
- {
+ void gen_trees_header(void) {
      FILE *header = fopen("trees.h", "w");
      int i;
  
      Assert (header != NULL, "Can't open trees.h");
      fprintf(header,

@@ -395,16 +455,30 @@
  
      fclose(header);
  }
  #endif /* GEN_TREES_H */
  
+ /* ===========================================================================
+  * Initialize a new block.
+  */
+ local void init_block(deflate_state *s) {
+     int n; /* iterates over tree elements */
+ 
+     /* Initialize the trees. */
+     for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+     for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+     for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+ 
+     s->dyn_ltree[END_BLOCK].Freq = 1;
+     s->opt_len = s->static_len = 0L;
+     s->sym_next = s->matches = 0;
+ }
+ 
  /* ===========================================================================
   * Initialize the tree data structures for a new zlib stream.
   */
- void ZLIB_INTERNAL _tr_init(s)
-     deflate_state *s;
- {
+ void ZLIB_INTERNAL _tr_init(deflate_state *s) {
      tr_static_init();
  
      s->l_desc.dyn_tree = s->dyn_ltree;
      s->l_desc.stat_desc = &static_l_desc;
  

@@ -423,28 +497,10 @@
  
      /* Initialize the first block of the first file: */
      init_block(s);
  }
  
- /* ===========================================================================
-  * Initialize a new block.
-  */
- local void init_block(s)
-     deflate_state *s;
- {
-     int n; /* iterates over tree elements */
- 
-     /* Initialize the trees. */
-     for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
-     for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
-     for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
- 
-     s->dyn_ltree[END_BLOCK].Freq = 1;
-     s->opt_len = s->static_len = 0L;
-     s->sym_next = s->matches = 0;
- }
- 
  #define SMALLEST 1
  /* Index within the heap array of least frequent node in the Huffman tree */
  
  
  /* ===========================================================================

@@ -470,15 +526,11 @@
   * Restore the heap property by moving down the tree starting at node k,
   * exchanging a node with the smallest of its two sons if necessary, stopping
   * when the heap property is re-established (each father smaller than its
   * two sons).
   */
- local void pqdownheap(s, tree, k)
-     deflate_state *s;
-     ct_data *tree;  /* the tree to restore */
-     int k;               /* node to move down */
- {
+ local void pqdownheap(deflate_state *s, ct_data *tree, int k) {
      int v = s->heap[k];
      int j = k << 1;  /* left son of k */
      while (j <= s->heap_len) {
          /* Set j to the smallest of the two sons: */
          if (j < s->heap_len &&

@@ -505,14 +557,11 @@
   * OUT assertions: the field len is set to the optimal bit length, the
   *     array bl_count contains the frequencies for each bit length.
   *     The length opt_len is updated; static_len is also updated if stree is
   *     not null.
   */
- local void gen_bitlen(s, desc)
-     deflate_state *s;
-     tree_desc *desc;    /* the tree descriptor */
- {
+ local void gen_bitlen(deflate_state *s, tree_desc *desc) {
      ct_data *tree        = desc->dyn_tree;
      int max_code         = desc->max_code;
      const ct_data *stree = desc->stat_desc->static_tree;
      const intf *extra    = desc->stat_desc->extra_bits;
      int base             = desc->stat_desc->extra_base;

@@ -583,65 +632,23 @@
              n--;
          }
      }
  }
  
- /* ===========================================================================
-  * Generate the codes for a given tree and bit counts (which need not be
-  * optimal).
-  * IN assertion: the array bl_count contains the bit length statistics for
-  * the given tree and the field len is set for all tree elements.
-  * OUT assertion: the field code is set for all tree elements of non
-  *     zero code length.
-  */
- local void gen_codes(tree, max_code, bl_count)
-     ct_data *tree;             /* the tree to decorate */
-     int max_code;              /* largest code with non zero frequency */
-     ushf *bl_count;            /* number of codes at each bit length */
- {
-     ush next_code[MAX_BITS+1]; /* next code value for each bit length */
-     unsigned code = 0;         /* running code value */
-     int bits;                  /* bit index */
-     int n;                     /* code index */
- 
-     /* The distribution counts are first used to generate the code values
-      * without bit reversal.
-      */
-     for (bits = 1; bits <= MAX_BITS; bits++) {
-         code = (code + bl_count[bits - 1]) << 1;
-         next_code[bits] = (ush)code;
-     }
-     /* Check that the bit counts in bl_count are consistent. The last code
-      * must be all ones.
-      */
-     Assert (code + bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
-             "inconsistent bit counts");
-     Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
- 
-     for (n = 0;  n <= max_code; n++) {
-         int len = tree[n].Len;
-         if (len == 0) continue;
-         /* Now reverse the bits */
-         tree[n].Code = (ush)bi_reverse(next_code[len]++, len);
- 
-         Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
-             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len] - 1));
-     }
- }
+ #ifdef DUMP_BL_TREE
+ #  include <stdio.h>
+ #endif
  
  /* ===========================================================================
   * Construct one Huffman tree and assigns the code bit strings and lengths.
   * Update the total bit length for the current block.
   * IN assertion: the field freq is set for all tree elements.
   * OUT assertions: the fields len and code are set to the optimal bit length
   *     and corresponding code. The length opt_len is updated; static_len is
   *     also updated if stree is not null. The field max_code is set.
   */
- local void build_tree(s, desc)
-     deflate_state *s;
-     tree_desc *desc; /* the tree descriptor */
- {
+ local void build_tree(deflate_state *s, tree_desc *desc) {
      ct_data *tree         = desc->dyn_tree;
      const ct_data *stree  = desc->stat_desc->static_tree;
      int elems             = desc->stat_desc->elems;
      int n, m;          /* iterate over heap elements */
      int max_code = -1; /* largest code with non zero frequency */

@@ -722,15 +729,11 @@
  
  /* ===========================================================================
   * Scan a literal or distance tree to determine the frequencies of the codes
   * in the bit length tree.
   */
- local void scan_tree(s, tree, max_code)
-     deflate_state *s;
-     ct_data *tree;   /* the tree to be scanned */
-     int max_code;    /* and its largest code of non zero frequency */
- {
+ local void scan_tree(deflate_state *s, ct_data *tree, int max_code) {
      int n;                     /* iterates over all tree elements */
      int prevlen = -1;          /* last emitted length */
      int curlen;                /* length of current code */
      int nextlen = tree[0].Len; /* length of next code */
      int count = 0;             /* repeat count of the current code */

@@ -767,15 +770,11 @@
  
  /* ===========================================================================
   * Send a literal or distance tree in compressed form, using the codes in
   * bl_tree.
   */
- local void send_tree(s, tree, max_code)
-     deflate_state *s;
-     ct_data *tree; /* the tree to be scanned */
-     int max_code;       /* and its largest code of non zero frequency */
- {
+ local void send_tree(deflate_state *s, ct_data *tree, int max_code) {
      int n;                     /* iterates over all tree elements */
      int prevlen = -1;          /* last emitted length */
      int curlen;                /* length of current code */
      int nextlen = tree[0].Len; /* length of next code */
      int count = 0;             /* repeat count of the current code */

@@ -818,13 +817,11 @@
  
  /* ===========================================================================
   * Construct the Huffman tree for the bit lengths and return the index in
   * bl_order of the last bit length code to send.
   */
- local int build_bl_tree(s)
-     deflate_state *s;
- {
+ local int build_bl_tree(deflate_state *s) {
      int max_blindex;  /* index of last bit length code of non zero freq */
  
      /* Determine the bit length frequencies for literal and distance trees */
      scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
      scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);

@@ -853,14 +850,12 @@
  /* ===========================================================================
   * Send the header for a block using dynamic Huffman trees: the counts, the
   * lengths of the bit length codes, the literal tree and the distance tree.
   * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
   */
- local void send_all_trees(s, lcodes, dcodes, blcodes)
-     deflate_state *s;
-     int lcodes, dcodes, blcodes; /* number of codes for each tree */
- {
+ local void send_all_trees(deflate_state *s, int lcodes, int dcodes,
+                           int blcodes) {
      int rank;                    /* index in bl_order */
  
      Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
      Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
              "too many codes");

@@ -882,16 +877,12 @@
  }
  
  /* ===========================================================================
   * Send a stored block
   */
- void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
-     deflate_state *s;
-     charf *buf;       /* input block */
-     ulg stored_len;   /* length of input block */
-     int last;         /* one if this is the last block for a file */
- {
+ void ZLIB_INTERNAL _tr_stored_block(deflate_state *s, charf *buf,
+                                     ulg stored_len, int last) {
      send_bits(s, (STORED_BLOCK<<1) + last, 3);  /* send block type */
      bi_windup(s);        /* align on byte boundary */
      put_short(s, (ush)stored_len);
      put_short(s, (ush)~stored_len);
      if (stored_len)

@@ -906,41 +897,129 @@
  }
  
  /* ===========================================================================
   * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
   */
- void ZLIB_INTERNAL _tr_flush_bits(s)
-     deflate_state *s;
- {
+ void ZLIB_INTERNAL _tr_flush_bits(deflate_state *s) {
      bi_flush(s);
  }
  
  /* ===========================================================================
   * Send one empty static block to give enough lookahead for inflate.
   * This takes 10 bits, of which 7 may remain in the bit buffer.
   */
- void ZLIB_INTERNAL _tr_align(s)
-     deflate_state *s;
- {
+ void ZLIB_INTERNAL _tr_align(deflate_state *s) {
      send_bits(s, STATIC_TREES<<1, 3);
      send_code(s, END_BLOCK, static_ltree);
  #ifdef ZLIB_DEBUG
      s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
  #endif
      bi_flush(s);
  }
  
+ /* ===========================================================================
+  * Send the block data compressed using the given Huffman trees
+  */
+ local void compress_block(deflate_state *s, const ct_data *ltree,
+                           const ct_data *dtree) {
+     unsigned dist;      /* distance of matched string */
+     int lc;             /* match length or unmatched char (if dist == 0) */
+     unsigned sx = 0;    /* running index in symbol buffers */
+     unsigned code;      /* the code to send */
+     int extra;          /* number of extra bits to send */
+ 
+     if (s->sym_next != 0) do {
+ #ifdef LIT_MEM
+         dist = s->d_buf[sx];
+         lc = s->l_buf[sx++];
+ #else
+         dist = s->sym_buf[sx++] & 0xff;
+         dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
+         lc = s->sym_buf[sx++];
+ #endif
+         if (dist == 0) {
+             send_code(s, lc, ltree); /* send a literal byte */
+             Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+         } else {
+             /* Here, lc is the match length - MIN_MATCH */
+             code = _length_code[lc];
+             send_code(s, code + LITERALS + 1, ltree);   /* send length code */
+             extra = extra_lbits[code];
+             if (extra != 0) {
+                 lc -= base_length[code];
+                 send_bits(s, lc, extra);       /* send the extra length bits */
+             }
+             dist--; /* dist is now the match distance - 1 */
+             code = d_code(dist);
+             Assert (code < D_CODES, "bad d_code");
+ 
+             send_code(s, code, dtree);       /* send the distance code */
+             extra = extra_dbits[code];
+             if (extra != 0) {
+                 dist -= (unsigned)base_dist[code];
+                 send_bits(s, dist, extra);   /* send the extra distance bits */
+             }
+         } /* literal or match pair ? */
+ 
+         /* Check for no overlay of pending_buf on needed symbols */
+ #ifdef LIT_MEM
+         Assert(s->pending < 2 * (s->lit_bufsize + sx), "pendingBuf overflow");
+ #else
+         Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
+ #endif
+ 
+     } while (sx < s->sym_next);
+ 
+     send_code(s, END_BLOCK, ltree);
+ }
+ 
+ /* ===========================================================================
+  * Check if the data type is TEXT or BINARY, using the following algorithm:
+  * - TEXT if the two conditions below are satisfied:
+  *    a) There are no non-portable control characters belonging to the
+  *       "block list" (0..6, 14..25, 28..31).
+  *    b) There is at least one printable character belonging to the
+  *       "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+  * - BINARY otherwise.
+  * - The following partially-portable control characters form a
+  *   "gray list" that is ignored in this detection algorithm:
+  *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+  * IN assertion: the fields Freq of dyn_ltree are set.
+  */
+ local int detect_data_type(deflate_state *s) {
+     /* block_mask is the bit mask of block-listed bytes
+      * set bits 0..6, 14..25, and 28..31
+      * 0xf3ffc07f = binary 11110011111111111100000001111111
+      */
+     unsigned long block_mask = 0xf3ffc07fUL;
+     int n;
+ 
+     /* Check for non-textual ("block-listed") bytes. */
+     for (n = 0; n <= 31; n++, block_mask >>= 1)
+         if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+             return Z_BINARY;
+ 
+     /* Check for textual ("allow-listed") bytes. */
+     if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+             || s->dyn_ltree[13].Freq != 0)
+         return Z_TEXT;
+     for (n = 32; n < LITERALS; n++)
+         if (s->dyn_ltree[n].Freq != 0)
+             return Z_TEXT;
+ 
+     /* There are no "block-listed" or "allow-listed" bytes:
+      * this stream either is empty or has tolerated ("gray-listed") bytes only.
+      */
+     return Z_BINARY;
+ }
+ 
  /* ===========================================================================
   * Determine the best encoding for the current block: dynamic trees, static
   * trees or store, and write out the encoded block.
   */
- void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
-     deflate_state *s;
-     charf *buf;       /* input block, or NULL if too old */
-     ulg stored_len;   /* length of input block */
-     int last;         /* one if this is the last block for a file */
- {
+ void ZLIB_INTERNAL _tr_flush_block(deflate_state *s, charf *buf,
+                                    ulg stored_len, int last) {
      ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
      int max_blindex = 0;  /* index of last bit length code of non zero freq */
  
      /* Build the Huffman trees unless a stored block is forced */
      if (s->level > 0) {

@@ -1033,18 +1112,19 @@
  
  /* ===========================================================================
   * Save the match info and tally the frequency counts. Return true if
   * the current block must be flushed.
   */
- int ZLIB_INTERNAL _tr_tally(s, dist, lc)
-     deflate_state *s;
-     unsigned dist;  /* distance of matched string */
-     unsigned lc;    /* match length - MIN_MATCH or unmatched char (dist==0) */
- {
+ int ZLIB_INTERNAL _tr_tally(deflate_state *s, unsigned dist, unsigned lc) {
+ #ifdef LIT_MEM
+     s->d_buf[s->sym_next] = (ush)dist;
+     s->l_buf[s->sym_next++] = (uch)lc;
+ #else
      s->sym_buf[s->sym_next++] = (uch)dist;
      s->sym_buf[s->sym_next++] = (uch)(dist >> 8);
      s->sym_buf[s->sym_next++] = (uch)lc;
+ #endif
      if (dist == 0) {
          /* lc is the unmatched char */
          s->dyn_ltree[lc].Freq++;
      } else {
          s->matches++;

@@ -1057,149 +1137,5 @@
          s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++;
          s->dyn_dtree[d_code(dist)].Freq++;
      }
      return (s->sym_next == s->sym_end);
  }
- 
- /* ===========================================================================
-  * Send the block data compressed using the given Huffman trees
-  */
- local void compress_block(s, ltree, dtree)
-     deflate_state *s;
-     const ct_data *ltree; /* literal tree */
-     const ct_data *dtree; /* distance tree */
- {
-     unsigned dist;      /* distance of matched string */
-     int lc;             /* match length or unmatched char (if dist == 0) */
-     unsigned sx = 0;    /* running index in sym_buf */
-     unsigned code;      /* the code to send */
-     int extra;          /* number of extra bits to send */
- 
-     if (s->sym_next != 0) do {
-         dist = s->sym_buf[sx++] & 0xff;
-         dist += (unsigned)(s->sym_buf[sx++] & 0xff) << 8;
-         lc = s->sym_buf[sx++];
-         if (dist == 0) {
-             send_code(s, lc, ltree); /* send a literal byte */
-             Tracecv(isgraph(lc), (stderr," '%c' ", lc));
-         } else {
-             /* Here, lc is the match length - MIN_MATCH */
-             code = _length_code[lc];
-             send_code(s, code + LITERALS + 1, ltree);   /* send length code */
-             extra = extra_lbits[code];
-             if (extra != 0) {
-                 lc -= base_length[code];
-                 send_bits(s, lc, extra);       /* send the extra length bits */
-             }
-             dist--; /* dist is now the match distance - 1 */
-             code = d_code(dist);
-             Assert (code < D_CODES, "bad d_code");
- 
-             send_code(s, code, dtree);       /* send the distance code */
-             extra = extra_dbits[code];
-             if (extra != 0) {
-                 dist -= (unsigned)base_dist[code];
-                 send_bits(s, dist, extra);   /* send the extra distance bits */
-             }
-         } /* literal or match pair ? */
- 
-         /* Check that the overlay between pending_buf and sym_buf is ok: */
-         Assert(s->pending < s->lit_bufsize + sx, "pendingBuf overflow");
- 
-     } while (sx < s->sym_next);
- 
-     send_code(s, END_BLOCK, ltree);
- }
- 
- /* ===========================================================================
-  * Check if the data type is TEXT or BINARY, using the following algorithm:
-  * - TEXT if the two conditions below are satisfied:
-  *    a) There are no non-portable control characters belonging to the
-  *       "block list" (0..6, 14..25, 28..31).
-  *    b) There is at least one printable character belonging to the
-  *       "allow list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
-  * - BINARY otherwise.
-  * - The following partially-portable control characters form a
-  *   "gray list" that is ignored in this detection algorithm:
-  *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
-  * IN assertion: the fields Freq of dyn_ltree are set.
-  */
- local int detect_data_type(s)
-     deflate_state *s;
- {
-     /* block_mask is the bit mask of block-listed bytes
-      * set bits 0..6, 14..25, and 28..31
-      * 0xf3ffc07f = binary 11110011111111111100000001111111
-      */
-     unsigned long block_mask = 0xf3ffc07fUL;
-     int n;
- 
-     /* Check for non-textual ("block-listed") bytes. */
-     for (n = 0; n <= 31; n++, block_mask >>= 1)
-         if ((block_mask & 1) && (s->dyn_ltree[n].Freq != 0))
-             return Z_BINARY;
- 
-     /* Check for textual ("allow-listed") bytes. */
-     if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
-             || s->dyn_ltree[13].Freq != 0)
-         return Z_TEXT;
-     for (n = 32; n < LITERALS; n++)
-         if (s->dyn_ltree[n].Freq != 0)
-             return Z_TEXT;
- 
-     /* There are no "block-listed" or "allow-listed" bytes:
-      * this stream either is empty or has tolerated ("gray-listed") bytes only.
-      */
-     return Z_BINARY;
- }
- 
- /* ===========================================================================
-  * Reverse the first len bits of a code, using straightforward code (a faster
-  * method would use a table)
-  * IN assertion: 1 <= len <= 15
-  */
- local unsigned bi_reverse(code, len)
-     unsigned code; /* the value to invert */
-     int len;       /* its bit length */
- {
-     register unsigned res = 0;
-     do {
-         res |= code & 1;
-         code >>= 1, res <<= 1;
-     } while (--len > 0);
-     return res >> 1;
- }
- 
- /* ===========================================================================
-  * Flush the bit buffer, keeping at most 7 bits in it.
-  */
- local void bi_flush(s)
-     deflate_state *s;
- {
-     if (s->bi_valid == 16) {
-         put_short(s, s->bi_buf);
-         s->bi_buf = 0;
-         s->bi_valid = 0;
-     } else if (s->bi_valid >= 8) {
-         put_byte(s, (Byte)s->bi_buf);
-         s->bi_buf >>= 8;
-         s->bi_valid -= 8;
-     }
- }
- 
- /* ===========================================================================
-  * Flush the bit buffer and align the output on a byte boundary
-  */
- local void bi_windup(s)
-     deflate_state *s;
- {
-     if (s->bi_valid > 8) {
-         put_short(s, s->bi_buf);
-     } else if (s->bi_valid > 0) {
-         put_byte(s, (Byte)s->bi_buf);
-     }
-     s->bi_buf = 0;
-     s->bi_valid = 0;
- #ifdef ZLIB_DEBUG
-     s->bits_sent = (s->bits_sent + 7) & ~7;
- #endif
- }
< prev index next >