public FlushBlock ( byte stored, int storedOffset, int storedLength, bool lastBlock ) : void | ||
stored | byte | Data to flush |
storedOffset | int | Index of first byte to flush |
storedLength | int | Count of bytes to flush |
lastBlock | bool | True if this is the last block |
return | void |
public void FlushBlock(byte[] stored, int storedOffset, int storedLength, bool lastBlock)
{
literalTree.freqs[EOF_SYMBOL]++;
// Build trees
literalTree.BuildTree();
distTree.BuildTree();
// Calculate bitlen frequency
literalTree.CalcBLFreq(blTree);
distTree.CalcBLFreq(blTree);
// Build bitlen tree
blTree.BuildTree();
int blTreeCodes = 4;
for (int i = 18; i > blTreeCodes; i--) {
if (blTree.length[BL_ORDER[i]] > 0) {
blTreeCodes = i + 1;
}
}
int opt_len = 14 + blTreeCodes * 3 + blTree.GetEncodedLength() +
literalTree.GetEncodedLength() + distTree.GetEncodedLength() +
extra_bits;
int static_len = extra_bits;
for (int i = 0; i < LITERAL_NUM; i++) {
static_len += literalTree.freqs[i] * staticLLength[i];
}
for (int i = 0; i < DIST_NUM; i++) {
static_len += distTree.freqs[i] * staticDLength[i];
}
if (opt_len >= static_len) {
// Force static trees
opt_len = static_len;
}
if (storedOffset >= 0 && storedLength + 4 < opt_len >> 3) {
// Store Block
// if (DeflaterConstants.DEBUGGING) {
// //Console.WriteLine("Storing, since " + storedLength + " < " + opt_len
// + " <= " + static_len);
// }
FlushStoredBlock(stored, storedOffset, storedLength, lastBlock);
} else if (opt_len == static_len) {
// Encode with static tree
pending.WriteBits((DeflaterConstants.STATIC_TREES << 1) + (lastBlock ? 1 : 0), 3);
literalTree.SetStaticCodes(staticLCodes, staticLLength);
distTree.SetStaticCodes(staticDCodes, staticDLength);
CompressBlock();
Reset();
} else {
// Encode with dynamic tree
pending.WriteBits((DeflaterConstants.DYN_TREES << 1) + (lastBlock ? 1 : 0), 3);
SendAllTrees(blTreeCodes);
CompressBlock();
Reset();
}
}
public void SetLevel(int lvl) { goodLength = DeflaterConstants.GOOD_LENGTH[lvl]; max_lazy = DeflaterConstants.MAX_LAZY[lvl]; niceLength = DeflaterConstants.NICE_LENGTH[lvl]; max_chain = DeflaterConstants.MAX_CHAIN[lvl]; if (DeflaterConstants.COMPR_FUNC[lvl] != comprFunc) { // if (DeflaterConstants.DEBUGGING) { // //Console.WriteLine("Change from "+comprFunc +" to " // + DeflaterConstants.COMPR_FUNC[lvl]); // } switch (comprFunc) { case DEFLATE_STORED: if (strstart > blockStart) { huffman.FlushStoredBlock(window, blockStart, strstart - blockStart, false); blockStart = strstart; } UpdateHash(); break; case DEFLATE_FAST: if (strstart > blockStart) { huffman.FlushBlock(window, blockStart, strstart - blockStart, false); blockStart = strstart; } break; case DEFLATE_SLOW: if (prevAvailable) { huffman.TallyLit(window[strstart - 1] & 0xff); } if (strstart > blockStart) { huffman.FlushBlock(window, blockStart, strstart - blockStart, false); blockStart = strstart; } prevAvailable = false; matchLen = MIN_MATCH - 1; break; } comprFunc = COMPR_FUNC[lvl]; } }