diff options
Diffstat (limited to 'compat/zlib/trees.c')
| -rw-r--r-- | compat/zlib/trees.c | 147 | 
1 files changed, 77 insertions, 70 deletions
diff --git a/compat/zlib/trees.c b/compat/zlib/trees.c index badf371..1fd7759 100644 --- a/compat/zlib/trees.c +++ b/compat/zlib/trees.c @@ -1,5 +1,6 @@  /* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2005 Jean-loup Gailly + * Copyright (C) 1995-2012 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   */ @@ -29,7 +30,7 @@   *          Addison-Wesley, 1983. ISBN 0-201-06672-6.   */ -/* @(#) $Id: trees.c,v 1.1 2008/12/18 14:14:59 dkf Exp $ */ +/* @(#) $Id$ */  /* #define GEN_TREES_H */ @@ -73,11 +74,6 @@ local const uch bl_order[BL_CODES]   * probability, to avoid transmitting the lengths for unused bit length codes.   */ -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ -  /* ===========================================================================   * Local data. These are initialized only once.   */ @@ -150,9 +146,9 @@ 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, ct_data *ltree, -                              ct_data *dtree)); -local void set_data_type  OF((deflate_state *s)); +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 value, int length));  local void bi_windup      OF((deflate_state *s));  local void bi_flush       OF((deflate_state *s)); @@ -203,12 +199,12 @@ local void send_bits(s, value, length)       * unused bits in value.       */      if (s->bi_valid > (int)Buf_size - length) { -        s->bi_buf |= (value << s->bi_valid); +        s->bi_buf |= (ush)value << s->bi_valid;          put_short(s, s->bi_buf);          s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);          s->bi_valid += length - Buf_size;      } else { -        s->bi_buf |= value << s->bi_valid; +        s->bi_buf |= (ush)value << s->bi_valid;          s->bi_valid += length;      }  } @@ -218,12 +214,12 @@ local void send_bits(s, value, length)  { int len = length;\    if (s->bi_valid > (int)Buf_size - len) {\      int val = value;\ -    s->bi_buf |= (val << s->bi_valid);\ +    s->bi_buf |= (ush)val << s->bi_valid;\      put_short(s, s->bi_buf);\      s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\      s->bi_valid += len - Buf_size;\    } else {\ -    s->bi_buf |= (value) << s->bi_valid;\ +    s->bi_buf |= (ush)(value) << s->bi_valid;\      s->bi_valid += len;\    }\  } @@ -250,11 +246,13 @@ local void tr_static_init()      if (static_init_done) return;      /* For some embedded targets, global variables are not initialized: */ +#ifdef NO_INIT_GLOBAL_POINTERS      static_l_desc.static_tree = static_ltree;      static_l_desc.extra_bits = extra_lbits;      static_d_desc.static_tree = static_dtree;      static_d_desc.extra_bits = extra_dbits;      static_bl_desc.extra_bits = extra_blbits; +#endif      /* Initialize the mapping length (0..255) -> length code (0..28) */      length = 0; @@ -348,13 +346,14 @@ void gen_trees_header()                  static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));      } -    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n"); +    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");      for (i = 0; i < DIST_CODE_LEN; i++) {          fprintf(header, "%2u%s", _dist_code[i],                  SEPARATOR(i, DIST_CODE_LEN-1, 20));      } -    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); +    fprintf(header, +        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");      for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {          fprintf(header, "%2u%s", _length_code[i],                  SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); @@ -379,7 +378,7 @@ void gen_trees_header()  /* ===========================================================================   * Initialize the tree data structures for a new zlib stream.   */ -void _tr_init(s) +void ZLIB_INTERNAL _tr_init(s)      deflate_state *s;  {      tr_static_init(); @@ -395,7 +394,6 @@ void _tr_init(s)      s->bi_buf = 0;      s->bi_valid = 0; -    s->last_eob_len = 8; /* enough lookahead for inflate */  #ifdef DEBUG      s->compressed_len = 0L;      s->bits_sent = 0L; @@ -864,13 +862,13 @@ local void send_all_trees(s, lcodes, dcodes, blcodes)  /* ===========================================================================   * Send a stored block   */ -void _tr_stored_block(s, buf, stored_len, eof) +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 eof;          /* true if this is the last block for a file */ +    int last;         /* one if this is the last block for a file */  { -    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */ +    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */  #ifdef DEBUG      s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;      s->compressed_len += (stored_len + 4) << 3; @@ -879,17 +877,19 @@ void _tr_stored_block(s, buf, stored_len, eof)  }  /* =========================================================================== + * 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; +{ +    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. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only.   */ -void _tr_align(s) +void ZLIB_INTERNAL _tr_align(s)      deflate_state *s;  {      send_bits(s, STATIC_TREES<<1, 3); @@ -898,31 +898,17 @@ void _tr_align(s)      s->compressed_len += 10L; /* 3 for block type, 7 for EOB */  #endif      bi_flush(s); -    /* Of the 10 bits for the empty block, we have already sent -     * (10 - bi_valid) bits. The lookahead for the last real code (before -     * the EOB of the previous block) was thus at least one plus the length -     * of the EOB plus what we have just sent of the empty static block. -     */ -    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { -        send_bits(s, STATIC_TREES<<1, 3); -        send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG -        s->compressed_len += 10L; -#endif -        bi_flush(s); -    } -    s->last_eob_len = 7;  }  /* ===========================================================================   * Determine the best encoding for the current block: dynamic trees, static   * trees or store, and output the encoded block to the zip file.   */ -void _tr_flush_block(s, buf, stored_len, eof) +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 eof;          /* true if this is the last block for a file */ +    int last;         /* one if this is the last block for a file */  {      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 */ @@ -931,8 +917,8 @@ void _tr_flush_block(s, buf, stored_len, eof)      if (s->level > 0) {          /* Check if the file is binary or text */ -        if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN) -            set_data_type(s); +        if (s->strm->data_type == Z_UNKNOWN) +            s->strm->data_type = detect_data_type(s);          /* Construct the literal and distance trees */          build_tree(s, (tree_desc *)(&(s->l_desc))); @@ -978,23 +964,25 @@ void _tr_flush_block(s, buf, stored_len, eof)           * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to           * transform a block into a stored block.           */ -        _tr_stored_block(s, buf, stored_len, eof); +        _tr_stored_block(s, buf, stored_len, last);  #ifdef FORCE_STATIC      } else if (static_lenb >= 0) { /* force static trees */  #else      } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {  #endif -        send_bits(s, (STATIC_TREES<<1)+eof, 3); -        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); +        send_bits(s, (STATIC_TREES<<1)+last, 3); +        compress_block(s, (const ct_data *)static_ltree, +                       (const ct_data *)static_dtree);  #ifdef DEBUG          s->compressed_len += 3 + s->static_len;  #endif      } else { -        send_bits(s, (DYN_TREES<<1)+eof, 3); +        send_bits(s, (DYN_TREES<<1)+last, 3);          send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,                         max_blindex+1); -        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); +        compress_block(s, (const ct_data *)s->dyn_ltree, +                       (const ct_data *)s->dyn_dtree);  #ifdef DEBUG          s->compressed_len += 3 + s->opt_len;  #endif @@ -1005,21 +993,21 @@ void _tr_flush_block(s, buf, stored_len, eof)       */      init_block(s); -    if (eof) { +    if (last) {          bi_windup(s);  #ifdef DEBUG          s->compressed_len += 7;  /* align on byte boundary */  #endif      }      Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, -           s->compressed_len-7*eof)); +           s->compressed_len-7*last));  }  /* ===========================================================================   * Save the match info and tally the frequency counts. Return true if   * the current block must be flushed.   */ -int _tr_tally (s, dist, lc) +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 (if dist==0) */ @@ -1071,8 +1059,8 @@ int _tr_tally (s, dist, lc)   */  local void compress_block(s, ltree, dtree)      deflate_state *s; -    ct_data *ltree; /* literal tree */ -    ct_data *dtree; /* distance tree */ +    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) */ @@ -1114,28 +1102,48 @@ local void compress_block(s, ltree, dtree)      } while (lx < s->last_lit);      send_code(s, END_BLOCK, ltree); -    s->last_eob_len = ltree[END_BLOCK].Len;  }  /* =========================================================================== - * Set the data type to BINARY or TEXT, using a crude approximation: - * set it to Z_TEXT if all symbols are either printable characters (33 to 255) - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise. + * 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 + *       "black list" (0..6, 14..25, 28..31). + *    b) There is at least one printable character belonging to the + *       "white 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 void set_data_type(s) +local int detect_data_type(s)      deflate_state *s;  { +    /* black_mask is the bit mask of black-listed bytes +     * set bits 0..6, 14..25, and 28..31 +     * 0xf3ffc07f = binary 11110011111111111100000001111111 +     */ +    unsigned long black_mask = 0xf3ffc07fUL;      int n; -    for (n = 0; n < 9; n++) +    /* Check for non-textual ("black-listed") bytes. */ +    for (n = 0; n <= 31; n++, black_mask >>= 1) +        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) +            return Z_BINARY; + +    /* Check for textual ("white-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) -            break; -    if (n == 9) -        for (n = 14; n < 32; n++) -            if (s->dyn_ltree[n].Freq != 0) -                break; -    s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY; +            return Z_TEXT; + +    /* There are no "black-listed" or "white-listed" bytes: +     * this stream either is empty or has tolerated ("gray-listed") bytes only. +     */ +    return Z_BINARY;  }  /* =========================================================================== @@ -1201,7 +1209,6 @@ local void copy_block(s, buf, len, header)      int      header;  /* true if block header must be written */  {      bi_windup(s);        /* align on byte boundary */ -    s->last_eob_len = 8; /* enough lookahead for inflate */      if (header) {          put_short(s, (ush)len);  | 
