internal void _tr_flush_block(int buf, int stored_len, bool eof)
{
int 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 (level > 0)
{
// Check if the file is ascii or binary
if (data_type == Z_UNKNOWN)
set_data_type();
// Construct the literal and distance trees
l_desc.build_tree(this);
d_desc.build_tree(this);
// 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 = SupportClass.URShift((opt_len + 3 + 7), 3);
static_lenb = SupportClass.URShift((static_len + 3 + 7), 3);
if (static_lenb <= opt_lenb)
opt_lenb = static_lenb;
}
else
{
opt_lenb = static_lenb = stored_len + 5; // force a stored block
}
if (stored_len + 4 <= opt_lenb && buf != - 1)
{
// 4: two words for the lengths
// 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.
_tr_stored_block(buf, stored_len, eof);
}
else if (static_lenb == opt_lenb)
{
send_bits((STATIC_TREES << 1) + (eof?1:0), 3);
compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
}
else
{
send_bits((DYN_TREES << 1) + (eof?1:0), 3);
send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
compress_block(dyn_ltree, dyn_dtree);
}
// The above check is made mod 2^32, for files larger than 512 MB
// and uLong implemented on 32 bits.
init_block();
if (eof)
{
bi_windup();
}
}