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
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 = SharedUtils.URShift ((opt_len + 3 + 7), 3);
static_lenb = SharedUtils.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.
_InitializeBlocks ();
if (eof) {
bi_windup ();
}
}