Exemple #1
0
static void copy_block(
    z_stream&	s,
    char*			buf,
    size_t			len,
    int				header )
{
    bi_windup( s );

    if( header )
    {
        put_short( s, (unsigned short) len );
        put_short( s, (unsigned short) ~len );
    }

    while( len-- )
        put_byte( s, *buf++ );
}
/* ===========================================================================
 * Determine the best encoding for the current block: dynamic trees, static
 * trees or store, and output the encoded block to the zip file. This function
 * returns the total compressed length for the file so far.
 */
word32 CodeTree::flush_block(byte *buf, word32 stored_len, int eof)
{
   word32 opt_lenb, static_lenb; /* opt_len and static_len in bytes */
   int max_blindex;  /* index of last bit length code of non zero freq */

   flag_buf[last_flags] = flags; /* Save the flags for the last 8 items */

   /* Construct the literal and distance trees */
   build_tree(&l_desc);
//   Tracev((stderr, "\nlit data: dyn %ld, stat %ld", opt_len, static_len));

   build_tree(&d_desc);
//   Tracev((stderr, "\ndist data: dyn %ld, stat %ld", opt_len, static_len));
   /* At this point, opt_len and static_len are the total bit lengths of
	* the compressed block data, excluding the tree representations.
	*/

   /* Build the bit length tree for the above two trees, and get the index
	* in bl_order of the last bit length code to send.
	*/
   max_blindex = build_bl_tree();

   /* Determine the best encoding. Compute first the block length in bytes */
   opt_lenb = (opt_len+3+7)>>3;
   static_lenb = (static_len+3+7)>>3;
   input_len += stored_len; /* for debugging only */

//   Trace((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
//           opt_lenb, opt_len, static_lenb, static_len, stored_len,
//           last_lit, last_dist));

   if (static_lenb <= opt_lenb) opt_lenb = static_lenb;

#ifdef FORCE_METHOD
   if (level == 2 && buf) /* force stored block */
#else
   if (stored_len+4 <= opt_lenb && buf) /* 4: two words for the lengths */
#endif
   {
	   /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
		* Otherwise we can't have processed more than WSIZE input bytes since
		* the last block flush, because compression would have been
		* successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
		* transform a block into a stored block.
		*/
	   /* send block type */
	   send_bits((STORED_BLOCK<<1)+eof, 3);
	   compressed_len = (compressed_len + 3 + 7) & ~7L;
	   compressed_len += (stored_len + 4) << 3;
	   /* with header */
	   copy_block(buf, (unsigned)stored_len, 1);
   }
#ifdef FORCE_METHOD
   else if (level == 3) /* force static trees */
#else
   else if (static_lenb == opt_lenb)
#endif
   {
	   send_bits((STATIC_TREES<<1)+eof, 3);
	   compress_block(static_ltree,static_dtree);
	   compressed_len += 3 + static_len;
   } else {
	   send_bits((DYN_TREES<<1)+eof, 3);
	   send_all_trees(l_desc.max_code+1, d_desc.max_code+1, max_blindex+1);
	   compress_block(dyn_ltree,dyn_dtree);
	   compressed_len += 3 + opt_len;
   }
//   assert (compressed_len == bits_sent);
   init_block();

   if (eof) {
//      assert (input_len == isize);
	  bi_windup();
	  compressed_len += 7;  /* align on byte boundary */
   }
//   Tracev((stderr,"\ncomprlen %lu(%lu) ", compressed_len>>3,
//          compressed_len-7*eof));

   return compressed_len >> 3;
}