mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01:00
lossless: Speed up ComputeCacheEntropy by 40 %
a total impact of 1 % on encoding speed This allows for performance neutral removal of the binary search in cache bits selection. This will give a small improvement in compression density. Change-Id: If5d4d59460fa1924ce71af977320834a47c2054a
This commit is contained in:
parent
1ceecdc871
commit
f722c8f0bd
@ -828,12 +828,9 @@ static void BackwardReferences2DLocality(int xsize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns entropy for the given cache bits.
|
// Returns entropy for the given cache bits.
|
||||||
static double ComputeCacheEntropy(const uint32_t* const argb,
|
static double ComputeCacheEntropy(const uint32_t* argb,
|
||||||
int xsize, int ysize,
|
|
||||||
const VP8LBackwardRefs* const refs,
|
const VP8LBackwardRefs* const refs,
|
||||||
int cache_bits) {
|
int cache_bits) {
|
||||||
int pixel_index = 0;
|
|
||||||
uint32_t k;
|
|
||||||
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;
|
double entropy = MAX_ENTROPY;
|
||||||
@ -847,33 +844,40 @@ static double ComputeCacheEntropy(const uint32_t* const argb,
|
|||||||
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
||||||
if (!cc_init) goto Error;
|
if (!cc_init) goto Error;
|
||||||
}
|
}
|
||||||
|
if (!use_color_cache) {
|
||||||
while (VP8LRefsCursorOk(&c)) {
|
while (VP8LRefsCursorOk(&c)) {
|
||||||
const PixOrCopy* const v = c.cur_pos;
|
VP8LHistogramAddSinglePixOrCopy(histo, c.cur_pos);
|
||||||
if (PixOrCopyIsLiteral(v)) {
|
VP8LRefsCursorNext(&c);
|
||||||
if (use_color_cache &&
|
}
|
||||||
VP8LColorCacheContains(&hashers, argb[pixel_index])) {
|
} else {
|
||||||
// push pixel as a cache index
|
while (VP8LRefsCursorOk(&c)) {
|
||||||
const int ix = VP8LColorCacheGetIndex(&hashers, argb[pixel_index]);
|
const PixOrCopy* const v = c.cur_pos;
|
||||||
const PixOrCopy token = PixOrCopyCreateCacheIdx(ix);
|
if (PixOrCopyIsLiteral(v)) {
|
||||||
VP8LHistogramAddSinglePixOrCopy(histo, &token);
|
const uint32_t pix = *argb++;
|
||||||
|
const uint32_t key = VP8LColorCacheGetIndex(&hashers, pix);
|
||||||
|
if (VP8LColorCacheLookup(&hashers, key) == pix) {
|
||||||
|
++histo->literal_[NUM_LITERAL_CODES + NUM_LENGTH_CODES + key];
|
||||||
|
} else {
|
||||||
|
VP8LColorCacheSet(&hashers, key, pix);
|
||||||
|
++histo->blue_[pix & 0xff];
|
||||||
|
++histo->literal_[(pix >> 8) & 0xff];
|
||||||
|
++histo->red_[(pix >> 16) & 0xff];
|
||||||
|
++histo->alpha_[pix >> 24];
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
VP8LHistogramAddSinglePixOrCopy(histo, v);
|
int len = PixOrCopyLength(v);
|
||||||
|
int code, extra_bits;
|
||||||
|
VP8LPrefixEncodeBits(len, &code, &extra_bits);
|
||||||
|
++histo->literal_[NUM_LITERAL_CODES + code];
|
||||||
|
VP8LPrefixEncodeBits(PixOrCopyDistance(v), &code, &extra_bits);
|
||||||
|
++histo->distance_[code];
|
||||||
|
do {
|
||||||
|
VP8LColorCacheInsert(&hashers, *argb++);
|
||||||
|
} while(--len != 0);
|
||||||
}
|
}
|
||||||
} else {
|
VP8LRefsCursorNext(&c);
|
||||||
VP8LHistogramAddSinglePixOrCopy(histo, v);
|
|
||||||
}
|
}
|
||||||
if (use_color_cache) {
|
|
||||||
for (k = 0; k < PixOrCopyLength(v); ++k) {
|
|
||||||
VP8LColorCacheInsert(&hashers, argb[pixel_index + k]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pixel_index += PixOrCopyLength(v);
|
|
||||||
VP8LRefsCursorNext(&c);
|
|
||||||
}
|
}
|
||||||
assert(pixel_index == xsize * ysize);
|
|
||||||
(void)xsize; // xsize is not used in non-debug compilations otherwise.
|
|
||||||
(void)ysize; // ysize is not used in non-debug compilations otherwise.
|
|
||||||
entropy = VP8LHistogramEstimateBits(histo) +
|
entropy = VP8LHistogramEstimateBits(histo) +
|
||||||
kSmallPenaltyForLargeCache * cache_bits;
|
kSmallPenaltyForLargeCache * cache_bits;
|
||||||
Error:
|
Error:
|
||||||
@ -916,14 +920,12 @@ static int CalculateBestCacheSize(const uint32_t* const argb,
|
|||||||
// 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 =
|
entropy_low = ComputeCacheEntropy(argb, refs, cache_bits_low);
|
||||||
ComputeCacheEntropy(argb, xsize, ysize, refs, cache_bits_low);
|
|
||||||
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 =
|
entropy_high = ComputeCacheEntropy(argb, refs, cache_bits_high);
|
||||||
ComputeCacheEntropy(argb, xsize, ysize, refs, cache_bits_high);
|
|
||||||
entropy_high += entropy_high * cache_bits_high * cost_mul;
|
entropy_high += entropy_high * cache_bits_high * cost_mul;
|
||||||
eval_high = 0;
|
eval_high = 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user