| Index: third_party/libwebp/dsp/filters.c
|
| diff --git a/third_party/libwebp/utils/filters.c b/third_party/libwebp/dsp/filters.c
|
| similarity index 76%
|
| copy from third_party/libwebp/utils/filters.c
|
| copy to third_party/libwebp/dsp/filters.c
|
| index 2d15bd0e4a4f59d07fb847c3bfaa070fa1d672a4..5c30f2e457e49d901741e39d0085ab31aac7897b 100644
|
| --- a/third_party/libwebp/utils/filters.c
|
| +++ b/third_party/libwebp/dsp/filters.c
|
| @@ -11,7 +11,7 @@
|
| //
|
| // Author: Urvang (urvang@google.com)
|
|
|
| -#include "./filters.h"
|
| +#include "./dsp.h"
|
| #include <assert.h>
|
| #include <stdlib.h>
|
| #include <string.h>
|
| @@ -75,16 +75,6 @@ static WEBP_INLINE void DoHorizontalFilter(const uint8_t* in,
|
| }
|
| }
|
|
|
| -static void HorizontalFilter(const uint8_t* data, int width, int height,
|
| - int stride, uint8_t* filtered_data) {
|
| - DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data);
|
| -}
|
| -
|
| -static void HorizontalUnfilter(int width, int height, int stride, int row,
|
| - int num_rows, uint8_t* data) {
|
| - DoHorizontalFilter(data, width, height, stride, row, num_rows, 1, data);
|
| -}
|
| -
|
| //------------------------------------------------------------------------------
|
| // Vertical filter.
|
|
|
| @@ -123,16 +113,6 @@ static WEBP_INLINE void DoVerticalFilter(const uint8_t* in,
|
| }
|
| }
|
|
|
| -static void VerticalFilter(const uint8_t* data, int width, int height,
|
| - int stride, uint8_t* filtered_data) {
|
| - DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data);
|
| -}
|
| -
|
| -static void VerticalUnfilter(int width, int height, int stride, int row,
|
| - int num_rows, uint8_t* data) {
|
| - DoVerticalFilter(data, width, height, stride, row, num_rows, 1, data);
|
| -}
|
| -
|
| //------------------------------------------------------------------------------
|
| // Gradient filter.
|
|
|
| @@ -181,86 +161,80 @@ static WEBP_INLINE void DoGradientFilter(const uint8_t* in,
|
| }
|
| }
|
|
|
| +#undef SANITY_CHECK
|
| +
|
| +//------------------------------------------------------------------------------
|
| +
|
| +static void HorizontalFilter(const uint8_t* data, int width, int height,
|
| + int stride, uint8_t* filtered_data) {
|
| + DoHorizontalFilter(data, width, height, stride, 0, height, 0, filtered_data);
|
| +}
|
| +
|
| +static void VerticalFilter(const uint8_t* data, int width, int height,
|
| + int stride, uint8_t* filtered_data) {
|
| + DoVerticalFilter(data, width, height, stride, 0, height, 0, filtered_data);
|
| +}
|
| +
|
| +
|
| static void GradientFilter(const uint8_t* data, int width, int height,
|
| int stride, uint8_t* filtered_data) {
|
| DoGradientFilter(data, width, height, stride, 0, height, 0, filtered_data);
|
| }
|
|
|
| +
|
| +//------------------------------------------------------------------------------
|
| +
|
| +static void VerticalUnfilter(int width, int height, int stride, int row,
|
| + int num_rows, uint8_t* data) {
|
| + DoVerticalFilter(data, width, height, stride, row, num_rows, 1, data);
|
| +}
|
| +
|
| +static void HorizontalUnfilter(int width, int height, int stride, int row,
|
| + int num_rows, uint8_t* data) {
|
| + DoHorizontalFilter(data, width, height, stride, row, num_rows, 1, data);
|
| +}
|
| +
|
| static void GradientUnfilter(int width, int height, int stride, int row,
|
| int num_rows, uint8_t* data) {
|
| DoGradientFilter(data, width, height, stride, row, num_rows, 1, data);
|
| }
|
|
|
| -#undef SANITY_CHECK
|
| +//------------------------------------------------------------------------------
|
| +// Init function
|
|
|
| -// -----------------------------------------------------------------------------
|
| -// Quick estimate of a potentially interesting filter mode to try.
|
| -
|
| -#define SMAX 16
|
| -#define SDIFF(a, b) (abs((a) - (b)) >> 4) // Scoring diff, in [0..SMAX)
|
| -
|
| -WEBP_FILTER_TYPE EstimateBestFilter(const uint8_t* data,
|
| - int width, int height, int stride) {
|
| - int i, j;
|
| - int bins[WEBP_FILTER_LAST][SMAX];
|
| - memset(bins, 0, sizeof(bins));
|
| -
|
| - // We only sample every other pixels. That's enough.
|
| - for (j = 2; j < height - 1; j += 2) {
|
| - const uint8_t* const p = data + j * stride;
|
| - int mean = p[0];
|
| - for (i = 2; i < width - 1; i += 2) {
|
| - const int diff0 = SDIFF(p[i], mean);
|
| - const int diff1 = SDIFF(p[i], p[i - 1]);
|
| - const int diff2 = SDIFF(p[i], p[i - width]);
|
| - const int grad_pred =
|
| - GradientPredictor(p[i - 1], p[i - width], p[i - width - 1]);
|
| - const int diff3 = SDIFF(p[i], grad_pred);
|
| - bins[WEBP_FILTER_NONE][diff0] = 1;
|
| - bins[WEBP_FILTER_HORIZONTAL][diff1] = 1;
|
| - bins[WEBP_FILTER_VERTICAL][diff2] = 1;
|
| - bins[WEBP_FILTER_GRADIENT][diff3] = 1;
|
| - mean = (3 * mean + p[i] + 2) >> 2;
|
| - }
|
| - }
|
| - {
|
| - int filter;
|
| - WEBP_FILTER_TYPE best_filter = WEBP_FILTER_NONE;
|
| - int best_score = 0x7fffffff;
|
| - for (filter = WEBP_FILTER_NONE; filter < WEBP_FILTER_LAST; ++filter) {
|
| - int score = 0;
|
| - for (i = 0; i < SMAX; ++i) {
|
| - if (bins[filter][i] > 0) {
|
| - score += i;
|
| - }
|
| - }
|
| - if (score < best_score) {
|
| - best_score = score;
|
| - best_filter = (WEBP_FILTER_TYPE)filter;
|
| - }
|
| - }
|
| - return best_filter;
|
| - }
|
| -}
|
| +WebPFilterFunc WebPFilters[WEBP_FILTER_LAST];
|
| +WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST];
|
|
|
| -#undef SMAX
|
| -#undef SDIFF
|
| +extern void VP8FiltersInitMIPSdspR2(void);
|
| +extern void VP8FiltersInitSSE2(void);
|
|
|
| -//------------------------------------------------------------------------------
|
| +static volatile VP8CPUInfo filters_last_cpuinfo_used =
|
| + (VP8CPUInfo)&filters_last_cpuinfo_used;
|
|
|
| -const WebPFilterFunc WebPFilters[WEBP_FILTER_LAST] = {
|
| - NULL, // WEBP_FILTER_NONE
|
| - HorizontalFilter, // WEBP_FILTER_HORIZONTAL
|
| - VerticalFilter, // WEBP_FILTER_VERTICAL
|
| - GradientFilter // WEBP_FILTER_GRADIENT
|
| -};
|
| +WEBP_TSAN_IGNORE_FUNCTION void VP8FiltersInit(void) {
|
| + if (filters_last_cpuinfo_used == VP8GetCPUInfo) return;
|
|
|
| -const WebPUnfilterFunc WebPUnfilters[WEBP_FILTER_LAST] = {
|
| - NULL, // WEBP_FILTER_NONE
|
| - HorizontalUnfilter, // WEBP_FILTER_HORIZONTAL
|
| - VerticalUnfilter, // WEBP_FILTER_VERTICAL
|
| - GradientUnfilter // WEBP_FILTER_GRADIENT
|
| -};
|
| + WebPUnfilters[WEBP_FILTER_NONE] = NULL;
|
| + WebPUnfilters[WEBP_FILTER_HORIZONTAL] = HorizontalUnfilter;
|
| + WebPUnfilters[WEBP_FILTER_VERTICAL] = VerticalUnfilter;
|
| + WebPUnfilters[WEBP_FILTER_GRADIENT] = GradientUnfilter;
|
|
|
| -//------------------------------------------------------------------------------
|
| + WebPFilters[WEBP_FILTER_NONE] = NULL;
|
| + WebPFilters[WEBP_FILTER_HORIZONTAL] = HorizontalFilter;
|
| + WebPFilters[WEBP_FILTER_VERTICAL] = VerticalFilter;
|
| + WebPFilters[WEBP_FILTER_GRADIENT] = GradientFilter;
|
|
|
| + if (VP8GetCPUInfo != NULL) {
|
| +#if defined(WEBP_USE_SSE2)
|
| + if (VP8GetCPUInfo(kSSE2)) {
|
| + VP8FiltersInitSSE2();
|
| + }
|
| +#endif
|
| +#if defined(WEBP_USE_MIPS_DSP_R2)
|
| + if (VP8GetCPUInfo(kMIPSdspR2)) {
|
| + VP8FiltersInitMIPSdspR2();
|
| + }
|
| +#endif
|
| + }
|
| + filters_last_cpuinfo_used = VP8GetCPUInfo;
|
| +}
|
|
|