| Index: third_party/libwebp/dsp/enc.c
|
| diff --git a/third_party/libwebp/dsp/enc.c b/third_party/libwebp/dsp/enc.c
|
| index 8899d50015c69051dc1624f84ebd5f9483ce1fad..f639f5570c436bc6b914376ab93fe786aa1083fb 100644
|
| --- a/third_party/libwebp/dsp/enc.c
|
| +++ b/third_party/libwebp/dsp/enc.c
|
| @@ -69,7 +69,7 @@ static void CollectHistogram(const uint8_t* ref, const uint8_t* pred,
|
|
|
| // Convert coefficients to bin.
|
| for (k = 0; k < 16; ++k) {
|
| - const int v = abs(out[k]) >> 3; // TODO(skal): add rounding?
|
| + const int v = abs(out[k]) >> 3;
|
| const int clipped_value = clip_max(v, MAX_COEFF_THRESH);
|
| ++distribution[clipped_value];
|
| }
|
| @@ -559,6 +559,7 @@ static int SSE4x4(const uint8_t* a, const uint8_t* b) {
|
|
|
| // Hadamard transform
|
| // Returns the weighted sum of the absolute value of transformed coefficients.
|
| +// w[] contains a row-major 4 by 4 symmetric matrix.
|
| static int TTransform(const uint8_t* in, const uint16_t* w) {
|
| int sum = 0;
|
| int tmp[16];
|
| @@ -636,7 +637,7 @@ static int QuantizeBlock(int16_t in[16], int16_t out[16],
|
| int level = QUANTDIV(coeff, iQ, B);
|
| if (level > MAX_LEVEL) level = MAX_LEVEL;
|
| if (sign) level = -level;
|
| - in[j] = level * Q;
|
| + in[j] = level * (int)Q;
|
| out[n] = level;
|
| if (level) last = n;
|
| } else {
|
| @@ -670,7 +671,7 @@ static int QuantizeBlockWHT(int16_t in[16], int16_t out[16],
|
| int level = QUANTDIV(coeff, iQ, B);
|
| if (level > MAX_LEVEL) level = MAX_LEVEL;
|
| if (sign) level = -level;
|
| - in[j] = level * Q;
|
| + in[j] = level * (int)Q;
|
| out[n] = level;
|
| if (level) last = n;
|
| } else {
|
| @@ -702,6 +703,68 @@ static void Copy16x8(const uint8_t* src, uint8_t* dst) {
|
| }
|
|
|
| //------------------------------------------------------------------------------
|
| +
|
| +static void SSIMAccumulateClipped(const uint8_t* src1, int stride1,
|
| + const uint8_t* src2, int stride2,
|
| + int xo, int yo, int W, int H,
|
| + VP8DistoStats* const stats) {
|
| + const int ymin = (yo - VP8_SSIM_KERNEL < 0) ? 0 : yo - VP8_SSIM_KERNEL;
|
| + const int ymax = (yo + VP8_SSIM_KERNEL > H - 1) ? H - 1
|
| + : yo + VP8_SSIM_KERNEL;
|
| + const int xmin = (xo - VP8_SSIM_KERNEL < 0) ? 0 : xo - VP8_SSIM_KERNEL;
|
| + const int xmax = (xo + VP8_SSIM_KERNEL > W - 1) ? W - 1
|
| + : xo + VP8_SSIM_KERNEL;
|
| + int x, y;
|
| + src1 += ymin * stride1;
|
| + src2 += ymin * stride2;
|
| + for (y = ymin; y <= ymax; ++y, src1 += stride1, src2 += stride2) {
|
| + for (x = xmin; x <= xmax; ++x) {
|
| + const int s1 = src1[x];
|
| + const int s2 = src2[x];
|
| + stats->w += 1;
|
| + stats->xm += s1;
|
| + stats->ym += s2;
|
| + stats->xxm += s1 * s1;
|
| + stats->xym += s1 * s2;
|
| + stats->yym += s2 * s2;
|
| + }
|
| + }
|
| +}
|
| +
|
| +static void SSIMAccumulate(const uint8_t* src1, int stride1,
|
| + const uint8_t* src2, int stride2,
|
| + VP8DistoStats* const stats) {
|
| + int x, y;
|
| + for (y = 0; y <= 2 * VP8_SSIM_KERNEL; ++y, src1 += stride1, src2 += stride2) {
|
| + for (x = 0; x <= 2 * VP8_SSIM_KERNEL; ++x) {
|
| + const int s1 = src1[x];
|
| + const int s2 = src2[x];
|
| + stats->w += 1;
|
| + stats->xm += s1;
|
| + stats->ym += s2;
|
| + stats->xxm += s1 * s1;
|
| + stats->xym += s1 * s2;
|
| + stats->yym += s2 * s2;
|
| + }
|
| + }
|
| +}
|
| +
|
| +VP8SSIMAccumulateFunc VP8SSIMAccumulate;
|
| +VP8SSIMAccumulateClippedFunc VP8SSIMAccumulateClipped;
|
| +
|
| +static volatile VP8CPUInfo ssim_last_cpuinfo_used =
|
| + (VP8CPUInfo)&ssim_last_cpuinfo_used;
|
| +
|
| +WEBP_TSAN_IGNORE_FUNCTION void VP8SSIMDspInit(void) {
|
| + if (ssim_last_cpuinfo_used == VP8GetCPUInfo) return;
|
| +
|
| + VP8SSIMAccumulate = SSIMAccumulate;
|
| + VP8SSIMAccumulateClipped = SSIMAccumulateClipped;
|
| +
|
| + ssim_last_cpuinfo_used = VP8GetCPUInfo;
|
| +}
|
| +
|
| +//------------------------------------------------------------------------------
|
| // Initialization
|
|
|
| // Speed-critical function pointers. We have to initialize them to the default
|
|
|