Fix a non-deterministic color cache size computation.

In case of impossible allocation, some value was returned while
computation should be stopped.

Change-Id: I5f85e264575be825e4261ab6fa63840c157cf5c2
This commit is contained in:
Vincent Rabaud 2017-01-10 18:53:19 +01:00
parent d712e20de0
commit 8874b16275

View File

@ -1526,17 +1526,18 @@ static void BackwardReferences2DLocality(int xsize,
} }
} }
// Returns entropy for the given cache bits. // Computes the entropy for the given cache bits.
static double ComputeCacheEntropy(const uint32_t* argb, // Returns 1 on success, 0 in case of allocation error.
const VP8LBackwardRefs* const refs, static int ComputeCacheEntropy(const uint32_t* argb,
int cache_bits) { const VP8LBackwardRefs* const refs,
int cache_bits, double* entropy) {
const int use_color_cache = (cache_bits > 0); const int use_color_cache = (cache_bits > 0);
int cc_init = 0; int cc_init = 0;
double entropy = MAX_ENTROPY;
const double kSmallPenaltyForLargeCache = 4.0; const double kSmallPenaltyForLargeCache = 4.0;
VP8LColorCache hashers; VP8LColorCache hashers;
VP8LRefsCursor c = VP8LRefsCursorInit(refs); VP8LRefsCursor c = VP8LRefsCursorInit(refs);
VP8LHistogram* histo = VP8LAllocateHistogram(cache_bits); VP8LHistogram* histo = VP8LAllocateHistogram(cache_bits);
int ok = 0;
if (histo == NULL) goto Error; if (histo == NULL) goto Error;
if (use_color_cache) { if (use_color_cache) {
@ -1577,12 +1578,13 @@ static double ComputeCacheEntropy(const uint32_t* argb,
VP8LRefsCursorNext(&c); VP8LRefsCursorNext(&c);
} }
} }
entropy = VP8LHistogramEstimateBits(histo) + *entropy = VP8LHistogramEstimateBits(histo) +
kSmallPenaltyForLargeCache * cache_bits; kSmallPenaltyForLargeCache * cache_bits;
ok = 1;
Error: Error:
if (cc_init) VP8LColorCacheClear(&hashers); if (cc_init) VP8LColorCacheClear(&hashers);
VP8LFreeHistogram(histo); VP8LFreeHistogram(histo);
return entropy; return ok;
} }
// Evaluate optimal cache bits for the local color cache. // Evaluate optimal cache bits for the local color cache.
@ -1616,15 +1618,20 @@ static int CalculateBestCacheSize(const uint32_t* const argb,
refs)) { refs)) {
return 0; return 0;
} }
*lz77_computed = 1;
// Do a binary search to find the optimal entropy for cache_bits. // Do a binary search to find the optimal entropy for cache_bits.
while (eval_low || eval_high) { while (eval_low || eval_high) {
if (eval_low) { if (eval_low) {
entropy_low = ComputeCacheEntropy(argb, refs, cache_bits_low); if (!ComputeCacheEntropy(argb, refs, cache_bits_low, &entropy_low)) {
return 0;
}
entropy_low += entropy_low * cache_bits_low * cost_mul; entropy_low += entropy_low * cache_bits_low * cost_mul;
eval_low = 0; eval_low = 0;
} }
if (eval_high) { if (eval_high) {
entropy_high = ComputeCacheEntropy(argb, refs, cache_bits_high); if (!ComputeCacheEntropy(argb, refs, cache_bits_high, &entropy_high )) {
return 0;
}
entropy_high += entropy_high * cache_bits_high * cost_mul; entropy_high += entropy_high * cache_bits_high * cost_mul;
eval_high = 0; eval_high = 0;
} }
@ -1639,7 +1646,6 @@ static int CalculateBestCacheSize(const uint32_t* const argb,
if (cache_bits_high != cache_bits_low) eval_high = 1; if (cache_bits_high != cache_bits_low) eval_high = 1;
} }
} }
*lz77_computed = 1;
return 1; return 1;
} }