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 (compressionLevel > 0)
{
// Check if the file is ascii or binary
if (data_type == Z_UNKNOWN)
set_data_type();
// Construct the literal and distance trees
treeLiterals.build_tree(this);
treeDistances.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 = (opt_len + 3 + 7) >> 3;
static_lenb = (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);
send_compressed_block(StaticTree.lengthAndLiteralsTreeCodes, StaticTree.distTreeCodes);
}
else
{
send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
send_all_trees(treeLiterals.max_code + 1, treeDistances.max_code + 1, max_blindex + 1);
send_compressed_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.
_InitializeBlocks();
if (eof)
{
bi_windup();
}
}