| Index: third_party/libwebp/enc/near_lossless.c
|
| diff --git a/third_party/libwebp/enc/near_lossless.c b/third_party/libwebp/enc/near_lossless.c
|
| index 9bc0f0e7860803834b915377ddd7ee4297521d4f..f4ab91f5716ba7fcbdad7b1acb21bd187c9f9ca2 100644
|
| --- a/third_party/libwebp/enc/near_lossless.c
|
| +++ b/third_party/libwebp/enc/near_lossless.c
|
| @@ -14,6 +14,7 @@
|
| // Author: Jyrki Alakuijala (jyrki@google.com)
|
| // Converted to C by Aleksander Kramarz (akramarz@google.com)
|
|
|
| +#include <assert.h>
|
| #include <stdlib.h>
|
|
|
| #include "../dsp/lossless.h"
|
| @@ -23,42 +24,14 @@
|
| #define MIN_DIM_FOR_NEAR_LOSSLESS 64
|
| #define MAX_LIMIT_BITS 5
|
|
|
| -// Computes quantized pixel value and distance from original value.
|
| -static void GetValAndDistance(int a, int initial, int bits,
|
| - int* const val, int* const distance) {
|
| - const int mask = ~((1 << bits) - 1);
|
| - *val = (initial & mask) | (initial >> (8 - bits));
|
| - *distance = 2 * abs(a - *val);
|
| -}
|
| -
|
| -// Clamps the value to range [0, 255].
|
| -static int Clamp8b(int val) {
|
| - const int min_val = 0;
|
| - const int max_val = 0xff;
|
| - return (val < min_val) ? min_val : (val > max_val) ? max_val : val;
|
| -}
|
| -
|
| -// Quantizes values {a, a+(1<<bits), a-(1<<bits)} and returns the nearest one.
|
| +// Quantizes the value up or down to a multiple of 1<<bits (or to 255),
|
| +// choosing the closer one, resolving ties using bankers' rounding.
|
| static int FindClosestDiscretized(int a, int bits) {
|
| - int best_val = a, i;
|
| - int min_distance = 256;
|
| -
|
| - for (i = -1; i <= 1; ++i) {
|
| - int candidate, distance;
|
| - const int val = Clamp8b(a + i * (1 << bits));
|
| - GetValAndDistance(a, val, bits, &candidate, &distance);
|
| - if (i != 0) {
|
| - ++distance;
|
| - }
|
| - // Smallest distance but favor i == 0 over i == -1 and i == 1
|
| - // since that keeps the overall intensity more constant in the
|
| - // images.
|
| - if (distance < min_distance) {
|
| - min_distance = distance;
|
| - best_val = candidate;
|
| - }
|
| - }
|
| - return best_val;
|
| + const int mask = (1 << bits) - 1;
|
| + const int biased = a + (mask >> 1) + ((a >> bits) & 1);
|
| + assert(bits > 0);
|
| + if (biased > 0xff) return 0xff;
|
| + return biased & ~mask;
|
| }
|
|
|
| // Applies FindClosestDiscretized to all channels of pixel.
|
| @@ -124,22 +97,11 @@ static void NearLossless(int xsize, int ysize, uint32_t* argb,
|
| }
|
| }
|
|
|
| -static int QualityToLimitBits(int quality) {
|
| - // quality mapping:
|
| - // 0..19 -> 5
|
| - // 0..39 -> 4
|
| - // 0..59 -> 3
|
| - // 0..79 -> 2
|
| - // 0..99 -> 1
|
| - // 100 -> 0
|
| - return MAX_LIMIT_BITS - quality / 20;
|
| -}
|
| -
|
| int VP8ApplyNearLossless(int xsize, int ysize, uint32_t* argb, int quality) {
|
| int i;
|
| uint32_t* const copy_buffer =
|
| (uint32_t*)WebPSafeMalloc(xsize * 3, sizeof(*copy_buffer));
|
| - const int limit_bits = QualityToLimitBits(quality);
|
| + const int limit_bits = VP8LNearLosslessBits(quality);
|
| assert(argb != NULL);
|
| assert(limit_bits >= 0);
|
| assert(limit_bits <= MAX_LIMIT_BITS);
|
|
|