/* Same as CalculateBlockSymbolSize, but with the histogram provided by the caller. */ static size_t CalculateBlockSymbolSizeGivenCounts(const size_t* ll_counts, const size_t* d_counts, const unsigned* ll_lengths, const unsigned* d_lengths, const ZopfliLZ77Store* lz77, size_t lstart, size_t lend) { size_t result = 0; size_t i; if (lstart + ZOPFLI_NUM_LL * 3 > lend) { return CalculateBlockSymbolSizeSmall( ll_lengths, d_lengths, lz77, lstart, lend); } else { for (i = 0; i < 256; i++) { result += ll_lengths[i] * ll_counts[i]; } for (i = 257; i < 286; i++) { result += ll_lengths[i] * ll_counts[i]; result += ZopfliGetLengthSymbolExtraBits(i) * ll_counts[i]; } for (i = 0; i < 30; i++) { result += d_lengths[i] * d_counts[i]; result += ZopfliGetDistSymbolExtraBits(i) * d_counts[i]; } result += ll_lengths[256]; /*end symbol*/ return result; } }
/* Calculates size of the part after the header and tree of an LZ77 block, in bits. */ static size_t CalculateBlockSymbolSize(const unsigned* ll_lengths, const unsigned* d_lengths, const ZopfliLZ77Store* lz77, size_t lstart, size_t lend) { size_t result = 0; size_t i; if (lstart + ZOPFLI_NUM_LL * 3 > lend) { for (i = lstart; i < lend; i++) { assert(i < lz77->size); assert(lz77->litlens[i] < 259); if (lz77->dists[i] == 0) { result += ll_lengths[lz77->litlens[i]]; } else { int ll_symbol = ZopfliGetLengthSymbol(lz77->litlens[i]); int d_symbol = ZopfliGetDistSymbol(lz77->dists[i]); result += ll_lengths[ll_symbol]; result += d_lengths[d_symbol]; result += ZopfliGetLengthSymbolExtraBits(ll_symbol); result += ZopfliGetDistSymbolExtraBits(d_symbol); } } } else { size_t ll_counts[ZOPFLI_NUM_LL]; size_t d_counts[ZOPFLI_NUM_D]; ZopfliLZ77GetHistogram(lz77, lstart, lend, ll_counts, d_counts); for (i = 0; i < 256; i++) { result += ll_lengths[i] * ll_counts[i]; } for (i = 257; i < 286; i++) { result += ll_lengths[i] * ll_counts[i]; result += ZopfliGetLengthSymbolExtraBits(i) * ll_counts[i]; } for (i = 0; i < 30; i++) { result += d_lengths[i] * d_counts[i]; result += ZopfliGetDistSymbolExtraBits(i) * d_counts[i]; } } result += ll_lengths[256]; /*end symbol*/ return result; }
/* Same as CalculateBlockSymbolSize, but for block size smaller than histogram size. */ static size_t CalculateBlockSymbolSizeSmall(const unsigned* ll_lengths, const unsigned* d_lengths, const ZopfliLZ77Store* lz77, size_t lstart, size_t lend) { size_t result = 0; size_t i; for (i = lstart; i < lend; i++) { assert(i < lz77->size); assert(lz77->litlens[i] < 259); if (lz77->dists[i] == 0) { result += ll_lengths[lz77->litlens[i]]; } else { int ll_symbol = ZopfliGetLengthSymbol(lz77->litlens[i]); int d_symbol = ZopfliGetDistSymbol(lz77->dists[i]); result += ll_lengths[ll_symbol]; result += d_lengths[d_symbol]; result += ZopfliGetLengthSymbolExtraBits(ll_symbol); result += ZopfliGetDistSymbolExtraBits(d_symbol); } } result += ll_lengths[256]; /*end symbol*/ return result; }