mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-27 06:08:21 +01:00
Tune BackwardReferencesLz77 for low_effort (m=0).
- Lower the threshold parameters for HashChainFindCopy. For 1000 image PNG corpus (m=0), this change yields speedup of 15-20% at lower quality range (0.25% drop in compression density) and about 10% for higher quality range without any drop in the compression density. Following is the compression stats (before/after) for method = 0: Before After bpp/MPs bpp/MPs q=0 2.8615/18.000 2.8651/18.631 q=5 2.8615/18.216 2.8650/20.517 q=10 2.8572/18.070 2.8650/21.992 q=15 2.8519/18.371 2.8584/21.747 q=20 2.8454/18.975 2.8515/20.448 q=25 2.8230/8.531 2.8253/9.585 // Compression density remains same for q-range [30-100] q=30 2.7310/7.706 2.7310/8.028 q=35 2.7253/6.855 2.7253/7.184 q=40 2.7231/6.364 2.7231/6.604 q=45 2.7216/5.844 2.7216/6.223 q=50 2.7196/5.210 2.7196/5.731 q=55 2.7208/4.766 2.7208/4.970 q=60 2.7195/4.495 2.7195/4.602 q=65 2.7185/4.024 2.7185/4.236 q=70 2.7174/3.699 2.7174/3.861 q=75 2.7164/3.449 2.7164/3.605 q=80 2.7161/3.222 2.7161/3.038 q=85 2.7153/2.919 2.7153/2.946 q=90 2.7145/2.766 2.7145/2.771 q=95 2.7124/2.548 2.7124/2.575 q=100 2.6873/2.253 2.6873/2.335 Change-Id: I0e17581fb71f6094032ad06c6203350bd502f9a1
This commit is contained in:
parent
b0b973c39b
commit
ea08466d34
@ -58,6 +58,8 @@ static int DistanceToPlaneCode(int xsize, int dist) {
|
|||||||
return dist + 120;
|
return dist + 120;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(vikasa): Evaluate loading (and comparing) 32/64 bits for the inner while
|
||||||
|
// loop.
|
||||||
static WEBP_INLINE int FindMatchLength(const uint32_t* const array1,
|
static WEBP_INLINE int FindMatchLength(const uint32_t* const array1,
|
||||||
const uint32_t* const array2,
|
const uint32_t* const array2,
|
||||||
int best_len_match,
|
int best_len_match,
|
||||||
@ -228,9 +230,13 @@ static void HashChainInsert(VP8LHashChain* const p,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void GetParamsForHashChainFindCopy(
|
static void GetParamsForHashChainFindCopy(
|
||||||
int quality, int* iter_max, int* len_for_unit_dist) {
|
int quality, int low_effort, int* iter_max, int* len_for_unit_dist) {
|
||||||
*iter_max = 8 + (quality * quality) / 40;
|
*iter_max = 8 + (quality * quality) / 40;
|
||||||
*len_for_unit_dist = 32 + (96 * quality) / 100;
|
*len_for_unit_dist = 32 + (96 * quality) / 100;
|
||||||
|
if (low_effort) {
|
||||||
|
*iter_max -= 2;
|
||||||
|
*len_for_unit_dist /= 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetWindowSizeForHashChain(int quality, int xsize) {
|
static int GetWindowSizeForHashChain(int quality, int xsize) {
|
||||||
@ -370,8 +376,8 @@ static int BackwardReferencesRle(int xsize, int ysize,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int BackwardReferencesLz77(int xsize, int ysize,
|
static int BackwardReferencesLz77(int xsize, int ysize,
|
||||||
const uint32_t* const argb,
|
const uint32_t* const argb, int cache_bits,
|
||||||
int cache_bits, int quality,
|
int quality, int low_effort,
|
||||||
VP8LHashChain* const hash_chain,
|
VP8LHashChain* const hash_chain,
|
||||||
VP8LBackwardRefs* const refs) {
|
VP8LBackwardRefs* const refs) {
|
||||||
int i;
|
int i;
|
||||||
@ -382,7 +388,8 @@ static int BackwardReferencesLz77(int xsize, int ysize,
|
|||||||
VP8LColorCache hashers;
|
VP8LColorCache hashers;
|
||||||
int iter_max, len_for_unit_dist;
|
int iter_max, len_for_unit_dist;
|
||||||
const int window_size = GetWindowSizeForHashChain(quality, xsize);
|
const int window_size = GetWindowSizeForHashChain(quality, xsize);
|
||||||
GetParamsForHashChainFindCopy(quality, &iter_max, &len_for_unit_dist);
|
GetParamsForHashChainFindCopy(quality, low_effort, &iter_max,
|
||||||
|
&len_for_unit_dist);
|
||||||
|
|
||||||
if (use_color_cache) {
|
if (use_color_cache) {
|
||||||
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
cc_init = VP8LColorCacheInit(&hashers, cache_bits);
|
||||||
@ -402,7 +409,7 @@ static int BackwardReferencesLz77(int xsize, int ysize,
|
|||||||
int len2 = 0;
|
int len2 = 0;
|
||||||
int k;
|
int k;
|
||||||
HashChainInsert(hash_chain, &argb[i], i);
|
HashChainInsert(hash_chain, &argb[i], i);
|
||||||
if (len < (max_len >> 2)) {
|
if ((len < (max_len >> 2)) && !low_effort) {
|
||||||
// Evaluate Alternative#2: Insert the pixel at 'i' as literal, and code
|
// Evaluate Alternative#2: Insert the pixel at 'i' as literal, and code
|
||||||
// the pixels starting at 'i + 1' using backward reference.
|
// the pixels starting at 'i + 1' using backward reference.
|
||||||
HashChainFindCopy(hash_chain, i + 1, xsize, argb, max_len - 1,
|
HashChainFindCopy(hash_chain, i + 1, xsize, argb, max_len - 1,
|
||||||
@ -582,7 +589,7 @@ static int BackwardReferencesHashChainDistanceOnly(
|
|||||||
const int min_distance_code = 2;
|
const int min_distance_code = 2;
|
||||||
int iter_max, len_for_unit_dist;
|
int iter_max, len_for_unit_dist;
|
||||||
const int window_size = GetWindowSizeForHashChain(quality, xsize);
|
const int window_size = GetWindowSizeForHashChain(quality, xsize);
|
||||||
GetParamsForHashChainFindCopy(quality, &iter_max, &len_for_unit_dist);
|
GetParamsForHashChainFindCopy(quality, 0, &iter_max, &len_for_unit_dist);
|
||||||
|
|
||||||
if (cost == NULL || cost_model == NULL) goto Error;
|
if (cost == NULL || cost_model == NULL) goto Error;
|
||||||
|
|
||||||
@ -892,7 +899,7 @@ static int CalculateBestCacheSize(const uint32_t* const argb,
|
|||||||
// Local color cache is disabled.
|
// Local color cache is disabled.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (!BackwardReferencesLz77(xsize, ysize, argb, cache_bits_low, quality,
|
if (!BackwardReferencesLz77(xsize, ysize, argb, cache_bits_low, quality, 0,
|
||||||
hash_chain, refs)) {
|
hash_chain, refs)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -961,7 +968,7 @@ static int BackwardRefsWithLocalCache(const uint32_t* const argb,
|
|||||||
|
|
||||||
VP8LBackwardRefs* VP8LGetBackwardReferences(
|
VP8LBackwardRefs* VP8LGetBackwardReferences(
|
||||||
int width, int height, const uint32_t* const argb, int quality,
|
int width, int height, const uint32_t* const argb, int quality,
|
||||||
int* cache_bits, VP8LHashChain* const hash_chain,
|
int low_effort, int* cache_bits, VP8LHashChain* const hash_chain,
|
||||||
VP8LBackwardRefs refs_array[2]) {
|
VP8LBackwardRefs refs_array[2]) {
|
||||||
int lz77_is_useful;
|
int lz77_is_useful;
|
||||||
int lz77_computed;
|
int lz77_computed;
|
||||||
@ -985,7 +992,7 @@ VP8LBackwardRefs* VP8LGetBackwardReferences(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!BackwardReferencesLz77(width, height, argb, *cache_bits, quality,
|
if (!BackwardReferencesLz77(width, height, argb, *cache_bits, quality,
|
||||||
hash_chain, refs_lz77)) {
|
low_effort, hash_chain, refs_lz77)) {
|
||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ static WEBP_INLINE void VP8LRefsCursorNext(VP8LRefsCursor* const c) {
|
|||||||
// refs[0] or refs[1].
|
// refs[0] or refs[1].
|
||||||
VP8LBackwardRefs* VP8LGetBackwardReferences(
|
VP8LBackwardRefs* VP8LGetBackwardReferences(
|
||||||
int width, int height, const uint32_t* const argb, int quality,
|
int width, int height, const uint32_t* const argb, int quality,
|
||||||
int* cache_bits, VP8LHashChain* const hash_chain,
|
int low_effort, int* cache_bits, VP8LHashChain* const hash_chain,
|
||||||
VP8LBackwardRefs refs[2]);
|
VP8LBackwardRefs refs[2]);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -685,7 +685,7 @@ static WebPEncodingError EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Calculate backward references from ARGB image.
|
// Calculate backward references from ARGB image.
|
||||||
refs = VP8LGetBackwardReferences(width, height, argb, quality, &cache_bits,
|
refs = VP8LGetBackwardReferences(width, height, argb, quality, 0, &cache_bits,
|
||||||
hash_chain, refs_array);
|
hash_chain, refs_array);
|
||||||
if (refs == NULL) {
|
if (refs == NULL) {
|
||||||
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
@ -785,7 +785,8 @@ static WebPEncodingError EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
// of refs_array[0] or refs_array[1].
|
// of refs_array[0] or refs_array[1].
|
||||||
// Calculate backward references from ARGB image.
|
// Calculate backward references from ARGB image.
|
||||||
best_refs = VP8LGetBackwardReferences(width, height, argb, quality,
|
best_refs = VP8LGetBackwardReferences(width, height, argb, quality,
|
||||||
cache_bits, hash_chain, refs_array);
|
low_effort, cache_bits, hash_chain,
|
||||||
|
refs_array);
|
||||||
if (best_refs == NULL || !VP8LBackwardRefsCopy(best_refs, &refs)) {
|
if (best_refs == NULL || !VP8LBackwardRefsCopy(best_refs, &refs)) {
|
||||||
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
|
||||||
goto Error;
|
goto Error;
|
||||||
|
Loading…
Reference in New Issue
Block a user