| Index: third_party/libwebp/enc/filter.c
|
| diff --git a/third_party/libwebp/enc/filter.c b/third_party/libwebp/enc/filter.c
|
| index dd27804b55a91462507dde42eedc80ed2609d47d..11db4bd8cd85db617e0ad76f431b180a0589365b 100644
|
| --- a/third_party/libwebp/enc/filter.c
|
| +++ b/third_party/libwebp/enc/filter.c
|
| @@ -13,6 +13,7 @@
|
|
|
| #include <assert.h>
|
| #include "./vp8enci.h"
|
| +#include "../dsp/dsp.h"
|
|
|
| // This table gives, for a given sharpness, the filtering strength to be
|
| // used (at least) in order to filter a given edge step delta.
|
| @@ -61,180 +62,6 @@ int VP8FilterStrengthFromDelta(int sharpness, int delta) {
|
| return kLevelsFromDelta[sharpness][pos];
|
| }
|
|
|
| -// -----------------------------------------------------------------------------
|
| -// NOTE: clip1, tables and InitTables are repeated entries of dsp.c
|
| -static uint8_t abs0[255 + 255 + 1]; // abs(i)
|
| -static uint8_t abs1[255 + 255 + 1]; // abs(i)>>1
|
| -static int8_t sclip1[1020 + 1020 + 1]; // clips [-1020, 1020] to [-128, 127]
|
| -static int8_t sclip2[112 + 112 + 1]; // clips [-112, 112] to [-16, 15]
|
| -static uint8_t clip1[255 + 510 + 1]; // clips [-255,510] to [0,255]
|
| -
|
| -static int tables_ok = 0;
|
| -
|
| -static void InitTables(void) {
|
| - if (!tables_ok) {
|
| - int i;
|
| - for (i = -255; i <= 255; ++i) {
|
| - abs0[255 + i] = (i < 0) ? -i : i;
|
| - abs1[255 + i] = abs0[255 + i] >> 1;
|
| - }
|
| - for (i = -1020; i <= 1020; ++i) {
|
| - sclip1[1020 + i] = (i < -128) ? -128 : (i > 127) ? 127 : i;
|
| - }
|
| - for (i = -112; i <= 112; ++i) {
|
| - sclip2[112 + i] = (i < -16) ? -16 : (i > 15) ? 15 : i;
|
| - }
|
| - for (i = -255; i <= 255 + 255; ++i) {
|
| - clip1[255 + i] = (i < 0) ? 0 : (i > 255) ? 255 : i;
|
| - }
|
| - tables_ok = 1;
|
| - }
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Edge filtering functions
|
| -
|
| -// 4 pixels in, 2 pixels out
|
| -static WEBP_INLINE void do_filter2(uint8_t* p, int step) {
|
| - const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
| - const int a = 3 * (q0 - p0) + sclip1[1020 + p1 - q1];
|
| - const int a1 = sclip2[112 + ((a + 4) >> 3)];
|
| - const int a2 = sclip2[112 + ((a + 3) >> 3)];
|
| - p[-step] = clip1[255 + p0 + a2];
|
| - p[ 0] = clip1[255 + q0 - a1];
|
| -}
|
| -
|
| -// 4 pixels in, 4 pixels out
|
| -static WEBP_INLINE void do_filter4(uint8_t* p, int step) {
|
| - const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
| - const int a = 3 * (q0 - p0);
|
| - const int a1 = sclip2[112 + ((a + 4) >> 3)];
|
| - const int a2 = sclip2[112 + ((a + 3) >> 3)];
|
| - const int a3 = (a1 + 1) >> 1;
|
| - p[-2*step] = clip1[255 + p1 + a3];
|
| - p[- step] = clip1[255 + p0 + a2];
|
| - p[ 0] = clip1[255 + q0 - a1];
|
| - p[ step] = clip1[255 + q1 - a3];
|
| -}
|
| -
|
| -// high edge-variance
|
| -static WEBP_INLINE int hev(const uint8_t* p, int step, int thresh) {
|
| - const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
| - return (abs0[255 + p1 - p0] > thresh) || (abs0[255 + q1 - q0] > thresh);
|
| -}
|
| -
|
| -static WEBP_INLINE int needs_filter(const uint8_t* p, int step, int thresh) {
|
| - const int p1 = p[-2*step], p0 = p[-step], q0 = p[0], q1 = p[step];
|
| - return (2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) <= thresh;
|
| -}
|
| -
|
| -static WEBP_INLINE int needs_filter2(const uint8_t* p,
|
| - int step, int t, int it) {
|
| - const int p3 = p[-4*step], p2 = p[-3*step], p1 = p[-2*step], p0 = p[-step];
|
| - const int q0 = p[0], q1 = p[step], q2 = p[2*step], q3 = p[3*step];
|
| - if ((2 * abs0[255 + p0 - q0] + abs1[255 + p1 - q1]) > t)
|
| - return 0;
|
| - return abs0[255 + p3 - p2] <= it && abs0[255 + p2 - p1] <= it &&
|
| - abs0[255 + p1 - p0] <= it && abs0[255 + q3 - q2] <= it &&
|
| - abs0[255 + q2 - q1] <= it && abs0[255 + q1 - q0] <= it;
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Simple In-loop filtering (Paragraph 15.2)
|
| -
|
| -static void SimpleVFilter16(uint8_t* p, int stride, int thresh) {
|
| - int i;
|
| - for (i = 0; i < 16; ++i) {
|
| - if (needs_filter(p + i, stride, thresh)) {
|
| - do_filter2(p + i, stride);
|
| - }
|
| - }
|
| -}
|
| -
|
| -static void SimpleHFilter16(uint8_t* p, int stride, int thresh) {
|
| - int i;
|
| - for (i = 0; i < 16; ++i) {
|
| - if (needs_filter(p + i * stride, 1, thresh)) {
|
| - do_filter2(p + i * stride, 1);
|
| - }
|
| - }
|
| -}
|
| -
|
| -static void SimpleVFilter16i(uint8_t* p, int stride, int thresh) {
|
| - int k;
|
| - for (k = 3; k > 0; --k) {
|
| - p += 4 * stride;
|
| - SimpleVFilter16(p, stride, thresh);
|
| - }
|
| -}
|
| -
|
| -static void SimpleHFilter16i(uint8_t* p, int stride, int thresh) {
|
| - int k;
|
| - for (k = 3; k > 0; --k) {
|
| - p += 4;
|
| - SimpleHFilter16(p, stride, thresh);
|
| - }
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -// Complex In-loop filtering (Paragraph 15.3)
|
| -
|
| -static WEBP_INLINE void FilterLoop24(uint8_t* p,
|
| - int hstride, int vstride, int size,
|
| - int thresh, int ithresh, int hev_thresh) {
|
| - while (size-- > 0) {
|
| - if (needs_filter2(p, hstride, thresh, ithresh)) {
|
| - if (hev(p, hstride, hev_thresh)) {
|
| - do_filter2(p, hstride);
|
| - } else {
|
| - do_filter4(p, hstride);
|
| - }
|
| - }
|
| - p += vstride;
|
| - }
|
| -}
|
| -
|
| -// on three inner edges
|
| -static void VFilter16i(uint8_t* p, int stride,
|
| - int thresh, int ithresh, int hev_thresh) {
|
| - int k;
|
| - for (k = 3; k > 0; --k) {
|
| - p += 4 * stride;
|
| - FilterLoop24(p, stride, 1, 16, thresh, ithresh, hev_thresh);
|
| - }
|
| -}
|
| -
|
| -static void HFilter16i(uint8_t* p, int stride,
|
| - int thresh, int ithresh, int hev_thresh) {
|
| - int k;
|
| - for (k = 3; k > 0; --k) {
|
| - p += 4;
|
| - FilterLoop24(p, 1, stride, 16, thresh, ithresh, hev_thresh);
|
| - }
|
| -}
|
| -
|
| -static void VFilter8i(uint8_t* u, uint8_t* v, int stride,
|
| - int thresh, int ithresh, int hev_thresh) {
|
| - FilterLoop24(u + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
| - FilterLoop24(v + 4 * stride, stride, 1, 8, thresh, ithresh, hev_thresh);
|
| -}
|
| -
|
| -static void HFilter8i(uint8_t* u, uint8_t* v, int stride,
|
| - int thresh, int ithresh, int hev_thresh) {
|
| - FilterLoop24(u + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
| - FilterLoop24(v + 4, 1, stride, 8, thresh, ithresh, hev_thresh);
|
| -}
|
| -
|
| -//------------------------------------------------------------------------------
|
| -
|
| -void (*VP8EncVFilter16i)(uint8_t*, int, int, int, int) = VFilter16i;
|
| -void (*VP8EncHFilter16i)(uint8_t*, int, int, int, int) = HFilter16i;
|
| -void (*VP8EncVFilter8i)(uint8_t*, uint8_t*, int, int, int, int) = VFilter8i;
|
| -void (*VP8EncHFilter8i)(uint8_t*, uint8_t*, int, int, int, int) = HFilter8i;
|
| -
|
| -void (*VP8EncSimpleVFilter16i)(uint8_t*, int, int) = SimpleVFilter16i;
|
| -void (*VP8EncSimpleHFilter16i)(uint8_t*, int, int) = SimpleHFilter16i;
|
| -
|
| //------------------------------------------------------------------------------
|
| // Paragraph 15.4: compute the inner-edge filtering strength
|
|
|
| @@ -266,14 +93,14 @@ static void DoFilter(const VP8EncIterator* const it, int level) {
|
| memcpy(y_dst, it->yuv_out_, YUV_SIZE * sizeof(uint8_t));
|
|
|
| if (enc->filter_hdr_.simple_ == 1) { // simple
|
| - VP8EncSimpleHFilter16i(y_dst, BPS, limit);
|
| - VP8EncSimpleVFilter16i(y_dst, BPS, limit);
|
| + VP8SimpleHFilter16i(y_dst, BPS, limit);
|
| + VP8SimpleVFilter16i(y_dst, BPS, limit);
|
| } else { // complex
|
| const int hev_thresh = (level >= 40) ? 2 : (level >= 15) ? 1 : 0;
|
| - VP8EncHFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
|
| - VP8EncHFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
|
| - VP8EncVFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
|
| - VP8EncVFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
|
| + VP8HFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
|
| + VP8HFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
|
| + VP8VFilter16i(y_dst, BPS, limit, ilevel, hev_thresh);
|
| + VP8VFilter8i(u_dst, v_dst, BPS, limit, ilevel, hev_thresh);
|
| }
|
| }
|
|
|
| @@ -387,7 +214,6 @@ static double GetMBSSIM(const uint8_t* yuv1, const uint8_t* yuv2) {
|
| void VP8InitFilter(VP8EncIterator* const it) {
|
| if (it->lf_stats_ != NULL) {
|
| int s, i;
|
| - InitTables();
|
| for (s = 0; s < NUM_MB_SEGMENTS; s++) {
|
| for (i = 0; i < MAX_LF_LEVELS; i++) {
|
| (*it->lf_stats_)[s][i] = 0;
|
| @@ -468,4 +294,3 @@ void VP8AdjustFilterStrength(VP8EncIterator* const it) {
|
| }
|
|
|
| // -----------------------------------------------------------------------------
|
| -
|
|
|