double ZopfliCalculateBlockSize(const unsigned short* litlens, const unsigned short* dists, size_t lstart, size_t lend, int btype) { size_t ll_counts[288]; size_t d_counts[32]; unsigned ll_lengths[288]; unsigned d_lengths[32]; double result = 3; /*bfinal and btype bits*/ assert(btype == 1 || btype == 2); /* This is not for uncompressed blocks. */ if(btype == 1) { GetFixedTree(ll_lengths, d_lengths); } else { ZopfliLZ77Counts(litlens, dists, lstart, lend, ll_counts, d_counts); ZopfliCalculateBitLengths(ll_counts, 288, 15, ll_lengths); ZopfliCalculateBitLengths(d_counts, 32, 15, d_lengths); PatchDistanceCodesForBuggyDecoders(d_lengths); result += CalculateTreeSize(ll_lengths, d_lengths, ll_counts, d_counts); } result += CalculateBlockSymbolSize( ll_lengths, d_lengths, litlens, dists, lstart, lend); return result; }
/* Calculates the bit lengths for the symbols for dynamic blocks. Chooses bit lengths that give the smallest size of tree encoding + encoding of all the symbols to have smallest output size. This are not necessarily the ideal Huffman bit lengths. */ static void GetDynamicLengths(const unsigned short* litlens, const unsigned short* dists, size_t lstart, size_t lend, unsigned* ll_lengths, unsigned* d_lengths) { size_t ll_counts[288]; size_t d_counts[32]; ZopfliLZ77Counts(litlens, dists, lstart, lend, ll_counts, d_counts); OptimizeHuffmanForRle(288, ll_counts); OptimizeHuffmanForRle(32, d_counts); ZopfliCalculateBitLengths(ll_counts, 288, 15, ll_lengths); ZopfliCalculateBitLengths(d_counts, 32, 15, d_lengths); PatchDistanceCodesForBuggyDecoders(d_lengths); }