diff options
Diffstat (limited to 'lib/libz/trees.c')
| -rw-r--r-- | lib/libz/trees.c | 54 | 
1 files changed, 28 insertions, 26 deletions
| diff --git a/lib/libz/trees.c b/lib/libz/trees.c index b02b5277f48a2..2497001742d3e 100644 --- a/lib/libz/trees.c +++ b/lib/libz/trees.c @@ -29,7 +29,7 @@   *          Addison-Wesley, 1983. ISBN 0-201-06672-6.   */ -/* @(#) $Id: trees.c,v 1.1.1.3 1999/01/10 09:46:57 peter Exp $ */ +/* $FreeBSD$ */  /* #define GEN_TREES_H */ @@ -250,13 +250,6 @@ local void tr_static_init()      if (static_init_done) return; -    /* For some embedded targets, global variables are not initialized: */ -    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; -      /* Initialize the mapping length (0..255) -> length code (0..28) */      length = 0;      for (code = 0; code < LENGTH_CODES-1; code++) { @@ -385,6 +378,8 @@ void _tr_init(s)  {      tr_static_init(); +    s->compressed_len = 0L; +      s->l_desc.dyn_tree = s->dyn_ltree;      s->l_desc.stat_desc = &static_l_desc; @@ -398,7 +393,6 @@ void _tr_init(s)      s->bi_valid = 0;      s->last_eob_len = 8; /* enough lookahead for inflate */  #ifdef DEBUG -    s->compressed_len = 0L;      s->bits_sent = 0L;  #endif @@ -871,10 +865,9 @@ void _tr_stored_block(s, buf, stored_len, eof)      int eof;          /* true if this is the last block for a file */  {      send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */ -#ifdef DEBUG      s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;      s->compressed_len += (stored_len + 4) << 3; -#endif +      copy_block(s, buf, (unsigned)stored_len, 1); /* with header */  } @@ -894,9 +887,7 @@ void _tr_align(s)  {      send_bits(s, STATIC_TREES<<1, 3);      send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG      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 @@ -906,9 +897,7 @@ void _tr_align(s)      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; @@ -916,9 +905,10 @@ void _tr_align(s)  /* ===========================================================================   * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. + * trees or store, and output the encoded block to the zip file. This function + * returns the total compressed length for the file so far.   */ -void _tr_flush_block(s, buf, stored_len, eof) +ulg _tr_flush_block(s, buf, stored_len, eof)      deflate_state *s;      charf *buf;       /* input block, or NULL if too old */      ulg stored_len;   /* length of input block */ @@ -965,6 +955,25 @@ void _tr_flush_block(s, buf, stored_len, eof)  	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */      } +    /* If compression failed and this is the first and last block, +     * and if the .zip file can be seeked (to rewrite the local header), +     * the whole file is transformed into a stored file: +     */ +#ifdef STORED_FILE_OK +#  ifdef FORCE_STORED_FILE +    if (eof && s->compressed_len == 0L) { /* force stored file */ +#  else +    if (stored_len <= opt_lenb && eof && s->compressed_len==0L && seekable()) { +#  endif +        /* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */ +        if (buf == (charf*)0) error ("block vanished"); + +        copy_block(buf, (unsigned)stored_len, 0); /* without header */ +        s->compressed_len = stored_len << 3; +        s->method = STORED; +    } else +#endif /* STORED_FILE_OK */ +  #ifdef FORCE_STORED      if (buf != (char*)0) { /* force stored block */  #else @@ -986,32 +995,25 @@ void _tr_flush_block(s, buf, stored_len, eof)  #endif          send_bits(s, (STATIC_TREES<<1)+eof, 3);          compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG          s->compressed_len += 3 + s->static_len; -#endif      } else {          send_bits(s, (DYN_TREES<<1)+eof, 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); -#ifdef DEBUG          s->compressed_len += 3 + s->opt_len; -#endif      }      Assert (s->compressed_len == s->bits_sent, "bad compressed size"); -    /* The above check is made mod 2^32, for files larger than 512 MB -     * and uLong implemented on 32 bits. -     */      init_block(s);      if (eof) {          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)); + +    return s->compressed_len >> 3;  }  /* =========================================================================== | 
