| Index: third_party/libwebp/dsp/upsampling_sse2.c
|
| diff --git a/third_party/libwebp/dsp/upsampling_sse2.c b/third_party/libwebp/dsp/upsampling_sse2.c
|
| index f31d04845e4a2b2902350fecfcaf556f6987b13f..0db0798c6d0655a25b76153914b65ba566c1c317 100644
|
| --- a/third_party/libwebp/dsp/upsampling_sse2.c
|
| +++ b/third_party/libwebp/dsp/upsampling_sse2.c
|
| @@ -13,10 +13,6 @@
|
|
|
| #include "./dsp.h"
|
|
|
| -#if defined(__cplusplus) || defined(c_plusplus)
|
| -extern "C" {
|
| -#endif
|
| -
|
| #if defined(WEBP_USE_SSE2)
|
|
|
| #include <assert.h>
|
| @@ -51,7 +47,7 @@ extern "C" {
|
| (out) = _mm_sub_epi8(tmp0, tmp4); /* (k + in + 1) / 2 - lsb_correction */ \
|
| } while (0)
|
|
|
| -// pack and store two alterning pixel rows
|
| +// pack and store two alternating pixel rows
|
| #define PACK_AND_STORE(a, b, da, db, out) do { \
|
| const __m128i t_a = _mm_avg_epu8(a, da); /* (9a + 3b + 3c + d + 8) / 16 */ \
|
| const __m128i t_b = _mm_avg_epu8(b, db); /* (3a + 9b + c + 3d + 8) / 16 */ \
|
| @@ -87,8 +83,8 @@ extern "C" {
|
| GET_M(ad, s, diag2); /* diag2 = (3a + b + c + 3d) / 8 */ \
|
| \
|
| /* pack the alternate pixels */ \
|
| - PACK_AND_STORE(a, b, diag1, diag2, &(out)[0 * 32]); \
|
| - PACK_AND_STORE(c, d, diag2, diag1, &(out)[2 * 32]); \
|
| + PACK_AND_STORE(a, b, diag1, diag2, out + 0); /* store top */ \
|
| + PACK_AND_STORE(c, d, diag2, diag1, out + 2 * 32); /* store bottom */ \
|
| }
|
|
|
| // Turn the macro into a function for reducing code-size when non-critical
|
| @@ -108,69 +104,68 @@ static void Upsample32Pixels(const uint8_t r1[], const uint8_t r2[],
|
| Upsample32Pixels(r1, r2, out); \
|
| }
|
|
|
| -#define CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, uv, \
|
| +#define CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, \
|
| top_dst, bottom_dst, cur_x, num_pixels) { \
|
| int n; \
|
| - if (top_y) { \
|
| - for (n = 0; n < (num_pixels); ++n) { \
|
| - FUNC(top_y[(cur_x) + n], (uv)[n], (uv)[32 + n], \
|
| - top_dst + ((cur_x) + n) * XSTEP); \
|
| - } \
|
| + for (n = 0; n < (num_pixels); ++n) { \
|
| + FUNC(top_y[(cur_x) + n], r_u[n], r_v[n], \
|
| + top_dst + ((cur_x) + n) * XSTEP); \
|
| } \
|
| - if (bottom_y) { \
|
| + if (bottom_y != NULL) { \
|
| for (n = 0; n < (num_pixels); ++n) { \
|
| - FUNC(bottom_y[(cur_x) + n], (uv)[64 + n], (uv)[64 + 32 + n], \
|
| + FUNC(bottom_y[(cur_x) + n], r_u[64 + n], r_v[64 + n], \
|
| bottom_dst + ((cur_x) + n) * XSTEP); \
|
| } \
|
| } \
|
| }
|
|
|
| +#define CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y, \
|
| + top_dst, bottom_dst, cur_x) do { \
|
| + FUNC##32(top_y + (cur_x), r_u, r_v, top_dst + (cur_x) * XSTEP); \
|
| + if (bottom_y != NULL) { \
|
| + FUNC##32(bottom_y + (cur_x), r_u + 64, r_v + 64, \
|
| + bottom_dst + (cur_x) * XSTEP); \
|
| + } \
|
| +} while (0)
|
| +
|
| #define SSE2_UPSAMPLE_FUNC(FUNC_NAME, FUNC, XSTEP) \
|
| static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \
|
| const uint8_t* top_u, const uint8_t* top_v, \
|
| const uint8_t* cur_u, const uint8_t* cur_v, \
|
| uint8_t* top_dst, uint8_t* bottom_dst, int len) { \
|
| - int block; \
|
| - /* 16 byte aligned array to cache reconstructed u and v */ \
|
| + int uv_pos, pos; \
|
| + /* 16byte-aligned array to cache reconstructed u and v */ \
|
| uint8_t uv_buf[4 * 32 + 15]; \
|
| - uint8_t* const r_uv = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \
|
| - const int uv_len = (len + 1) >> 1; \
|
| - /* 17 pixels must be read-able for each block */ \
|
| - const int num_blocks = (uv_len - 1) >> 4; \
|
| - const int leftover = uv_len - num_blocks * 16; \
|
| - const int last_pos = 1 + 32 * num_blocks; \
|
| - \
|
| - const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1; \
|
| - const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1; \
|
| + uint8_t* const r_u = (uint8_t*)((uintptr_t)(uv_buf + 15) & ~15); \
|
| + uint8_t* const r_v = r_u + 32; \
|
| \
|
| - assert(len > 0); \
|
| - /* Treat the first pixel in regular way */ \
|
| - if (top_y) { \
|
| - const int u0 = (top_u[0] + u_diag) >> 1; \
|
| - const int v0 = (top_v[0] + v_diag) >> 1; \
|
| - FUNC(top_y[0], u0, v0, top_dst); \
|
| + assert(top_y != NULL); \
|
| + { /* Treat the first pixel in regular way */ \
|
| + const int u_diag = ((top_u[0] + cur_u[0]) >> 1) + 1; \
|
| + const int v_diag = ((top_v[0] + cur_v[0]) >> 1) + 1; \
|
| + const int u0_t = (top_u[0] + u_diag) >> 1; \
|
| + const int v0_t = (top_v[0] + v_diag) >> 1; \
|
| + FUNC(top_y[0], u0_t, v0_t, top_dst); \
|
| + if (bottom_y != NULL) { \
|
| + const int u0_b = (cur_u[0] + u_diag) >> 1; \
|
| + const int v0_b = (cur_v[0] + v_diag) >> 1; \
|
| + FUNC(bottom_y[0], u0_b, v0_b, bottom_dst); \
|
| + } \
|
| } \
|
| - if (bottom_y) { \
|
| - const int u0 = (cur_u[0] + u_diag) >> 1; \
|
| - const int v0 = (cur_v[0] + v_diag) >> 1; \
|
| - FUNC(bottom_y[0], u0, v0, bottom_dst); \
|
| + /* For UPSAMPLE_32PIXELS, 17 u/v values must be read-able for each block */ \
|
| + for (pos = 1, uv_pos = 0; pos + 32 + 1 <= len; pos += 32, uv_pos += 16) { \
|
| + UPSAMPLE_32PIXELS(top_u + uv_pos, cur_u + uv_pos, r_u); \
|
| + UPSAMPLE_32PIXELS(top_v + uv_pos, cur_v + uv_pos, r_v); \
|
| + CONVERT2RGB_32(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst, pos); \
|
| } \
|
| - \
|
| - for (block = 0; block < num_blocks; ++block) { \
|
| - UPSAMPLE_32PIXELS(top_u, cur_u, r_uv + 0 * 32); \
|
| - UPSAMPLE_32PIXELS(top_v, cur_v, r_uv + 1 * 32); \
|
| - CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, r_uv, top_dst, bottom_dst, \
|
| - 32 * block + 1, 32) \
|
| - top_u += 16; \
|
| - cur_u += 16; \
|
| - top_v += 16; \
|
| - cur_v += 16; \
|
| + if (len > 1) { \
|
| + const int left_over = ((len + 1) >> 1) - (pos >> 1); \
|
| + assert(left_over > 0); \
|
| + UPSAMPLE_LAST_BLOCK(top_u + uv_pos, cur_u + uv_pos, left_over, r_u); \
|
| + UPSAMPLE_LAST_BLOCK(top_v + uv_pos, cur_v + uv_pos, left_over, r_v); \
|
| + CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, top_dst, bottom_dst, \
|
| + pos, len - pos); \
|
| } \
|
| - \
|
| - UPSAMPLE_LAST_BLOCK(top_u, cur_u, leftover, r_uv + 0 * 32); \
|
| - UPSAMPLE_LAST_BLOCK(top_v, cur_v, leftover, r_uv + 1 * 32); \
|
| - CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, r_uv, top_dst, bottom_dst, \
|
| - last_pos, len - last_pos); \
|
| }
|
|
|
| // SSE2 variants of the fancy upsampler.
|
| @@ -184,6 +179,7 @@ SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePairSSE2, VP8YuvToBgra, 4)
|
| #undef UPSAMPLE_32PIXELS
|
| #undef UPSAMPLE_LAST_BLOCK
|
| #undef CONVERT2RGB
|
| +#undef CONVERT2RGB_32
|
| #undef SSE2_UPSAMPLE_FUNC
|
|
|
| #endif // FANCY_UPSAMPLING
|
| @@ -192,10 +188,13 @@ SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePairSSE2, VP8YuvToBgra, 4)
|
|
|
| //------------------------------------------------------------------------------
|
|
|
| +#ifdef FANCY_UPSAMPLING
|
| +
|
| extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */];
|
|
|
| void WebPInitUpsamplersSSE2(void) {
|
| #if defined(WEBP_USE_SSE2)
|
| + VP8YUVInitSSE2();
|
| WebPUpsamplers[MODE_RGB] = UpsampleRgbLinePairSSE2;
|
| WebPUpsamplers[MODE_RGBA] = UpsampleRgbaLinePairSSE2;
|
| WebPUpsamplers[MODE_BGR] = UpsampleBgrLinePairSSE2;
|
| @@ -210,8 +209,10 @@ void WebPInitPremultiplySSE2(void) {
|
| #endif // WEBP_USE_SSE2
|
| }
|
|
|
| -#if defined(__cplusplus) || defined(c_plusplus)
|
| -} // extern "C"
|
| -#endif
|
| +#else
|
| +
|
| +// this empty function is to avoid an empty .o
|
| +void WebPInitPremultiplySSE2(void) {}
|
|
|
| +#endif // FANCY_UPSAMPLING
|
|
|
|
|