/* 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 ZopfliLZ77Store* lz77, size_t lstart, size_t lend, unsigned* ll_lengths, unsigned* d_lengths) { size_t ll_counts[ZOPFLI_NUM_LL]; size_t d_counts[ZOPFLI_NUM_D]; ZopfliLZ77GetHistogram(lz77, lstart, lend, ll_counts, d_counts); ll_counts[256] = 1; /* End symbol. */ OptimizeHuffmanForRle(ZOPFLI_NUM_LL, ll_counts); OptimizeHuffmanForRle(ZOPFLI_NUM_D, d_counts); ZopfliCalculateBitLengths(ll_counts, ZOPFLI_NUM_LL, 15, ll_lengths); ZopfliCalculateBitLengths(d_counts, ZOPFLI_NUM_D, 15, d_lengths); PatchDistanceCodesForBuggyDecoders(d_lengths); }
/* 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); }
void VP8LCreateHuffmanTree(uint32_t* const histogram, int tree_depth_limit, uint8_t* const buf_rle, HuffmanTree* const huff_tree, HuffmanTreeCode* const huff_code) { const int num_symbols = huff_code->num_symbols; memset(buf_rle, 0, num_symbols * sizeof(*buf_rle)); OptimizeHuffmanForRle(num_symbols, buf_rle, histogram); GenerateOptimalTree(histogram, num_symbols, huff_tree, tree_depth_limit, huff_code->code_lengths); // Create the actual bit codes for the bit lengths. ConvertBitDepthsToSymbols(huff_code); }
int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit, HuffmanTreeCode* const tree) { const int num_symbols = tree->num_symbols; if (!OptimizeHuffmanForRle(num_symbols, histogram)) { return 0; } if (!GenerateOptimalTree(histogram, num_symbols, tree_depth_limit, tree->code_lengths)) { return 0; } // Create the actual bit codes for the bit lengths. ConvertBitDepthsToSymbols(tree); return 1; }
/* Tries out OptimizeHuffmanForRle for this block, if the result is smaller, uses it, otherwise keeps the original. Returns size of encoded tree and data in bits, not including the 3-bit block header. */ static double TryOptimizeHuffmanForRle( const ZopfliLZ77Store* lz77, size_t lstart, size_t lend, const size_t* ll_counts, const size_t* d_counts, unsigned* ll_lengths, unsigned* d_lengths) { size_t ll_counts2[ZOPFLI_NUM_LL]; size_t d_counts2[ZOPFLI_NUM_D]; unsigned ll_lengths2[ZOPFLI_NUM_LL]; unsigned d_lengths2[ZOPFLI_NUM_D]; double treesize; double datasize; double treesize2; double datasize2; treesize = CalculateTreeSize(ll_lengths, d_lengths); datasize = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts, ll_lengths, d_lengths, lz77, lstart, lend); memcpy(ll_counts2, ll_counts, sizeof(ll_counts2)); memcpy(d_counts2, d_counts, sizeof(d_counts2)); OptimizeHuffmanForRle(ZOPFLI_NUM_LL, ll_counts2); OptimizeHuffmanForRle(ZOPFLI_NUM_D, d_counts2); ZopfliCalculateBitLengths(ll_counts2, ZOPFLI_NUM_LL, 15, ll_lengths2); ZopfliCalculateBitLengths(d_counts2, ZOPFLI_NUM_D, 15, d_lengths2); PatchDistanceCodesForBuggyDecoders(d_lengths2); treesize2 = CalculateTreeSize(ll_lengths2, d_lengths2); datasize2 = CalculateBlockSymbolSizeGivenCounts(ll_counts, d_counts, ll_lengths2, d_lengths2, lz77, lstart, lend); if (treesize2 + datasize2 < treesize + datasize) { memcpy(ll_lengths, ll_lengths2, sizeof(ll_lengths2)); memcpy(d_lengths, d_lengths2, sizeof(d_lengths2)); return treesize2 + datasize2; } return treesize + datasize; }