| Index: third_party/libwebp/enc/backward_references.c
|
| diff --git a/third_party/libwebp/enc/backward_references.c b/third_party/libwebp/enc/backward_references.c
|
| index db4f430df5e96438be54615945aec7da67a26f05..77b4be7432f0b909005a0999ee275e0aaa23bc91 100644
|
| --- a/third_party/libwebp/enc/backward_references.c
|
| +++ b/third_party/libwebp/enc/backward_references.c
|
| @@ -156,14 +156,14 @@ static void GetParamsForHashChainFindCopy(int quality, int xsize,
|
| *window_size = (max_window_size > WINDOW_SIZE) ? WINDOW_SIZE
|
| : max_window_size;
|
| *iter_pos = 8 + (quality >> 3);
|
| - // For lower entropy images, the rigourous search loop in HashChainFindCopy
|
| + // For lower entropy images, the rigorous search loop in HashChainFindCopy
|
| // can be relaxed.
|
| *iter_limit = (cache_bits > 0) ? iter_neg : iter_neg / 2;
|
| }
|
|
|
| static int HashChainFindCopy(const HashChain* const p,
|
| int base_position, int xsize_signed,
|
| - const uint32_t* const argb, int maxlen,
|
| + const uint32_t* const argb, int max_len,
|
| int window_size, int iter_pos, int iter_limit,
|
| int* const distance_ptr,
|
| int* const length_ptr) {
|
| @@ -176,25 +176,34 @@ static int HashChainFindCopy(const HashChain* const p,
|
| (base_position > window_size) ? base_position - window_size : 0;
|
| int pos;
|
| assert(xsize > 0);
|
| + if (max_len > MAX_LENGTH) {
|
| + max_len = MAX_LENGTH;
|
| + }
|
| for (pos = p->hash_to_first_index_[GetPixPairHash64(argb_start)];
|
| pos >= min_pos;
|
| pos = p->chain_[pos]) {
|
| uint64_t val;
|
| uint32_t curr_length;
|
| uint32_t distance;
|
| + const uint64_t* const ptr1 =
|
| + (const uint64_t*)(argb + pos + best_length - 1);
|
| + const uint64_t* const ptr2 =
|
| + (const uint64_t*)(argb_start + best_length - 1);
|
| +
|
| if (iter_pos < 0) {
|
| if (iter_pos < iter_limit || best_val >= 0xff0000) {
|
| break;
|
| }
|
| }
|
| --iter_pos;
|
| - if (argb[pos + best_length - 1] != argb_start[best_length - 1]) {
|
| - continue;
|
| - }
|
| - curr_length = FindMatchLength(argb + pos, argb_start, maxlen);
|
| - if (curr_length < best_length) {
|
| - continue;
|
| - }
|
| +
|
| + // Before 'expensive' linear match, check if the two arrays match at the
|
| + // current best length index and also for the succeeding elements.
|
| + if (*ptr1 != *ptr2) continue;
|
| +
|
| + curr_length = FindMatchLength(argb + pos, argb_start, max_len);
|
| + if (curr_length < best_length) continue;
|
| +
|
| distance = (uint32_t)(base_position - pos);
|
| val = curr_length << 16;
|
| // Favoring 2d locality here gives savings for certain images.
|
| @@ -213,7 +222,7 @@ static int HashChainFindCopy(const HashChain* const p,
|
| best_val = val;
|
| best_length = curr_length;
|
| best_distance = distance;
|
| - if (curr_length >= MAX_LENGTH) {
|
| + if (curr_length >= (uint32_t)max_len) {
|
| break;
|
| }
|
| if ((best_distance == 1 || distance == xsize) &&
|
| @@ -291,11 +300,8 @@ static int BackwardReferencesHashChain(int xsize, int ysize,
|
| int offset = 0;
|
| int len = 0;
|
| if (i < pix_count - 1) { // FindCopy(i,..) reads pixels at [i] and [i + 1].
|
| - int maxlen = pix_count - i;
|
| - if (maxlen > MAX_LENGTH) {
|
| - maxlen = MAX_LENGTH;
|
| - }
|
| - HashChainFindCopy(hash_chain, i, xsize, argb, maxlen,
|
| + int max_len = pix_count - i;
|
| + HashChainFindCopy(hash_chain, i, xsize, argb, max_len,
|
| window_size, iter_pos, iter_limit,
|
| &offset, &len);
|
| }
|
| @@ -307,11 +313,8 @@ static int BackwardReferencesHashChain(int xsize, int ysize,
|
| int k;
|
| HashChainInsert(hash_chain, &argb[i], i);
|
| if (i < pix_count - 2) { // FindCopy(i+1,..) reads [i + 1] and [i + 2].
|
| - int maxlen = pix_count - (i + 1);
|
| - if (maxlen > MAX_LENGTH) {
|
| - maxlen = MAX_LENGTH;
|
| - }
|
| - HashChainFindCopy(hash_chain, i + 1, xsize, argb, maxlen,
|
| + int max_len = pix_count - (i + 1);
|
| + HashChainFindCopy(hash_chain, i + 1, xsize, argb, max_len,
|
| window_size, iter_pos, iter_limit,
|
| &offset2, &len2);
|
| if (len2 > len + 1) {
|
| @@ -321,10 +324,10 @@ static int BackwardReferencesHashChain(int xsize, int ysize,
|
| const int ix = VP8LColorCacheGetIndex(&hashers, pixel);
|
| refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
|
| } else {
|
| + if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
|
| refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel);
|
| }
|
| ++refs->size;
|
| - if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
|
| i++; // Backward reference to be done for next pixel.
|
| len = len2;
|
| offset = offset2;
|
| @@ -354,10 +357,10 @@ static int BackwardReferencesHashChain(int xsize, int ysize,
|
| const int ix = VP8LColorCacheGetIndex(&hashers, pixel);
|
| refs->refs[refs->size] = PixOrCopyCreateCacheIdx(ix);
|
| } else {
|
| + if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
|
| refs->refs[refs->size] = PixOrCopyCreateLiteral(pixel);
|
| }
|
| ++refs->size;
|
| - if (use_color_cache) VP8LColorCacheInsert(&hashers, pixel);
|
| if (i + 1 < pix_count) {
|
| HashChainInsert(hash_chain, &argb[i], i);
|
| }
|
| @@ -459,16 +462,16 @@ static WEBP_INLINE double GetCacheCost(const CostModel* const m, uint32_t idx) {
|
|
|
| static WEBP_INLINE double GetLengthCost(const CostModel* const m,
|
| uint32_t length) {
|
| - int code, extra_bits_count, extra_bits_value;
|
| - PrefixEncode(length, &code, &extra_bits_count, &extra_bits_value);
|
| - return m->literal_[VALUES_IN_BYTE + code] + extra_bits_count;
|
| + int code, extra_bits;
|
| + VP8LPrefixEncodeBits(length, &code, &extra_bits);
|
| + return m->literal_[VALUES_IN_BYTE + code] + extra_bits;
|
| }
|
|
|
| static WEBP_INLINE double GetDistanceCost(const CostModel* const m,
|
| uint32_t distance) {
|
| - int code, extra_bits_count, extra_bits_value;
|
| - PrefixEncode(distance, &code, &extra_bits_count, &extra_bits_value);
|
| - return m->distance_[code] + extra_bits_count;
|
| + int code, extra_bits;
|
| + VP8LPrefixEncodeBits(distance, &code, &extra_bits);
|
| + return m->distance_[code] + extra_bits;
|
| }
|
|
|
| static int BackwardReferencesHashChainDistanceOnly(
|
| @@ -522,11 +525,8 @@ static int BackwardReferencesHashChainDistanceOnly(
|
| int offset = 0;
|
| int len = 0;
|
| if (i < pix_count - 1) { // FindCopy reads pixels at [i] and [i + 1].
|
| - int maxlen = shortmax ? 2 : MAX_LENGTH;
|
| - if (maxlen > pix_count - i) {
|
| - maxlen = pix_count - i;
|
| - }
|
| - HashChainFindCopy(hash_chain, i, xsize, argb, maxlen,
|
| + int max_len = shortmax ? 2 : pix_count - i;
|
| + HashChainFindCopy(hash_chain, i, xsize, argb, max_len,
|
| window_size, iter_pos, iter_limit,
|
| &offset, &len);
|
| }
|
| @@ -577,13 +577,13 @@ static int BackwardReferencesHashChainDistanceOnly(
|
| const int ix = VP8LColorCacheGetIndex(&hashers, argb[i]);
|
| cost_val += GetCacheCost(cost_model, ix) * mul0;
|
| } else {
|
| + if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
| cost_val += GetLiteralCost(cost_model, argb[i]) * mul1;
|
| }
|
| if (cost[i] > cost_val) {
|
| cost[i] = (float)cost_val;
|
| dist_array[i] = 1; // only one is inserted.
|
| }
|
| - if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
| }
|
| next_symbol: ;
|
| }
|
| @@ -650,12 +650,12 @@ static int BackwardReferencesHashChainFollowChosenPath(
|
| for (ix = 0; ix < chosen_path_size; ++ix, ++size) {
|
| int offset = 0;
|
| int len = 0;
|
| - int maxlen = chosen_path[ix];
|
| - if (maxlen != 1) {
|
| - HashChainFindCopy(hash_chain, i, xsize, argb, maxlen,
|
| + int max_len = chosen_path[ix];
|
| + if (max_len != 1) {
|
| + HashChainFindCopy(hash_chain, i, xsize, argb, max_len,
|
| window_size, iter_pos, iter_limit,
|
| &offset, &len);
|
| - assert(len == maxlen);
|
| + assert(len == max_len);
|
| refs->refs[size] = PixOrCopyCreateCopy(offset, len);
|
| if (use_color_cache) {
|
| for (k = 0; k < len; ++k) {
|
| @@ -675,9 +675,9 @@ static int BackwardReferencesHashChainFollowChosenPath(
|
| const int idx = VP8LColorCacheGetIndex(&hashers, argb[i]);
|
| refs->refs[size] = PixOrCopyCreateCacheIdx(idx);
|
| } else {
|
| + if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
| refs->refs[size] = PixOrCopyCreateLiteral(argb[i]);
|
| }
|
| - if (use_color_cache) VP8LColorCacheInsert(&hashers, argb[i]);
|
| if (i + 1 < pix_count) {
|
| HashChainInsert(hash_chain, &argb[i], i);
|
| }
|
| @@ -780,8 +780,8 @@ int VP8LGetBackwardReferences(int width, int height,
|
|
|
| // Choose appropriate backward reference.
|
| if (lz77_is_useful) {
|
| - // TraceBackwards is costly. Don't execute it at lower quality (q <= 10).
|
| - const int try_lz77_trace_backwards = (quality > 10);
|
| + // TraceBackwards is costly. Don't execute it at lower quality.
|
| + const int try_lz77_trace_backwards = (quality >= 25);
|
| *best = refs_lz77; // default guess: lz77 is better
|
| VP8LClearBackwardRefs(&refs_rle);
|
| if (try_lz77_trace_backwards) {
|
|
|