| Index: third_party/libwebp/dsp/upsampling.c
|
| diff --git a/third_party/libwebp/dsp/upsampling.c b/third_party/libwebp/dsp/upsampling.c
|
| index c88a17ad9bebd99c3ce613705e6e05f36e323a9b..9ca04927b9b639c5e31acd6360647179afe5b52c 100644
|
| --- a/third_party/libwebp/dsp/upsampling.c
|
| +++ b/third_party/libwebp/dsp/upsampling.c
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2011 Google Inc.
|
| +// Copyright 2011 Google Inc. All Rights Reserved.
|
| //
|
| // This code is licensed under the same terms as WebM:
|
| // Software License Agreement: http://www.webmproject.org/license/software/
|
| @@ -11,7 +11,6 @@
|
|
|
| #include "./dsp.h"
|
| #include "./yuv.h"
|
| -#include "../dec/webpi.h"
|
|
|
| #if defined(__cplusplus) || defined(c_plusplus)
|
| extern "C" {
|
| @@ -24,7 +23,6 @@ extern "C" {
|
|
|
| // Fancy upsampling functions to convert YUV to RGB
|
| WebPUpsampleLinePairFunc WebPUpsamplers[MODE_LAST];
|
| -WebPUpsampleLinePairFunc WebPUpsamplersKeepAlpha[MODE_LAST];
|
|
|
| // Given samples laid out in a square as:
|
| // [a b]
|
| @@ -101,11 +99,6 @@ UPSAMPLE_FUNC(UpsampleBgraLinePair, VP8YuvToBgra, 4)
|
| UPSAMPLE_FUNC(UpsampleArgbLinePair, VP8YuvToArgb, 4)
|
| UPSAMPLE_FUNC(UpsampleRgba4444LinePair, VP8YuvToRgba4444, 2)
|
| UPSAMPLE_FUNC(UpsampleRgb565LinePair, VP8YuvToRgb565, 2)
|
| -// These two don't erase the alpha value
|
| -UPSAMPLE_FUNC(UpsampleRgbKeepAlphaLinePair, VP8YuvToRgb, 4)
|
| -UPSAMPLE_FUNC(UpsampleBgrKeepAlphaLinePair, VP8YuvToBgr, 4)
|
| -UPSAMPLE_FUNC(UpsampleArgbKeepAlphaLinePair, VP8YuvToArgbKeepA, 4)
|
| -UPSAMPLE_FUNC(UpsampleRgba4444KeepAlphaLinePair, VP8YuvToRgba4444KeepA, 2)
|
|
|
| #undef LOAD_UV
|
| #undef UPSAMPLE_FUNC
|
| @@ -156,10 +149,56 @@ const WebPSampleLinePairFunc WebPSamplers[MODE_LAST] = {
|
| SampleBgraLinePair, // MODE_BGRA
|
| SampleArgbLinePair, // MODE_ARGB
|
| SampleRgba4444LinePair, // MODE_RGBA_4444
|
| - SampleRgb565LinePair // MODE_RGB_565
|
| + SampleRgb565LinePair, // MODE_RGB_565
|
| + SampleRgbaLinePair, // MODE_rgbA
|
| + SampleBgraLinePair, // MODE_bgrA
|
| + SampleArgbLinePair, // MODE_Argb
|
| + SampleRgba4444LinePair // MODE_rgbA_4444
|
| };
|
|
|
| //------------------------------------------------------------------------------
|
| +
|
| +#if !defined(FANCY_UPSAMPLING)
|
| +#define DUAL_SAMPLE_FUNC(FUNC_NAME, FUNC) \
|
| +static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y, \
|
| + const uint8_t* top_u, const uint8_t* top_v, \
|
| + const uint8_t* bot_u, const uint8_t* bot_v, \
|
| + uint8_t* top_dst, uint8_t* bot_dst, int len) { \
|
| + const int half_len = len >> 1; \
|
| + int x; \
|
| + if (top_dst != NULL) { \
|
| + for (x = 0; x < half_len; ++x) { \
|
| + FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x + 0); \
|
| + FUNC(top_y[2 * x + 1], top_u[x], top_v[x], top_dst + 8 * x + 4); \
|
| + } \
|
| + if (len & 1) FUNC(top_y[2 * x + 0], top_u[x], top_v[x], top_dst + 8 * x); \
|
| + } \
|
| + if (bot_dst != NULL) { \
|
| + for (x = 0; x < half_len; ++x) { \
|
| + FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x + 0); \
|
| + FUNC(bot_y[2 * x + 1], bot_u[x], bot_v[x], bot_dst + 8 * x + 4); \
|
| + } \
|
| + if (len & 1) FUNC(bot_y[2 * x + 0], bot_u[x], bot_v[x], bot_dst + 8 * x); \
|
| + } \
|
| +}
|
| +
|
| +DUAL_SAMPLE_FUNC(DualLineSamplerBGRA, VP8YuvToBgra)
|
| +DUAL_SAMPLE_FUNC(DualLineSamplerARGB, VP8YuvToArgb)
|
| +#undef DUAL_SAMPLE_FUNC
|
| +
|
| +#endif // !FANCY_UPSAMPLING
|
| +
|
| +WebPUpsampleLinePairFunc WebPGetLinePairConverter(int alpha_is_last) {
|
| + WebPInitUpsamplers();
|
| + VP8YUVInit();
|
| +#ifdef FANCY_UPSAMPLING
|
| + return WebPUpsamplers[alpha_is_last ? MODE_BGRA : MODE_ARGB];
|
| +#else
|
| + return (alpha_is_last ? DualLineSamplerBGRA : DualLineSamplerARGB);
|
| +#endif
|
| +}
|
| +
|
| +//------------------------------------------------------------------------------
|
| // YUV444 converter
|
|
|
| #define YUV444_FUNC(FUNC_NAME, FUNC, XSTEP) \
|
| @@ -186,10 +225,88 @@ const WebPYUV444Converter WebPYUV444Converters[MODE_LAST] = {
|
| Yuv444ToBgra, // MODE_BGRA
|
| Yuv444ToArgb, // MODE_ARGB
|
| Yuv444ToRgba4444, // MODE_RGBA_4444
|
| - Yuv444ToRgb565 // MODE_RGB_565
|
| + Yuv444ToRgb565, // MODE_RGB_565
|
| + Yuv444ToRgba, // MODE_rgbA
|
| + Yuv444ToBgra, // MODE_bgrA
|
| + Yuv444ToArgb, // MODE_Argb
|
| + Yuv444ToRgba4444 // MODE_rgbA_4444
|
| };
|
|
|
| //------------------------------------------------------------------------------
|
| +// Premultiplied modes
|
| +
|
| +// non dithered-modes
|
| +
|
| +// (x * a * 32897) >> 23 is bit-wise equivalent to (int)(x * a / 255.)
|
| +// for all 8bit x or a. For bit-wise equivalence to (int)(x * a / 255. + .5),
|
| +// one can use instead: (x * a * 65793 + (1 << 23)) >> 24
|
| +#if 1 // (int)(x * a / 255.)
|
| +#define MULTIPLIER(a) ((a) * 32897UL)
|
| +#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
|
| +#else // (int)(x * a / 255. + .5)
|
| +#define MULTIPLIER(a) ((a) * 65793UL)
|
| +#define PREMULTIPLY(x, m) (((x) * (m) + (1UL << 23)) >> 24)
|
| +#endif
|
| +
|
| +static void ApplyAlphaMultiply(uint8_t* rgba, int alpha_first,
|
| + int w, int h, int stride) {
|
| + while (h-- > 0) {
|
| + uint8_t* const rgb = rgba + (alpha_first ? 1 : 0);
|
| + const uint8_t* const alpha = rgba + (alpha_first ? 0 : 3);
|
| + int i;
|
| + for (i = 0; i < w; ++i) {
|
| + const uint32_t a = alpha[4 * i];
|
| + if (a != 0xff) {
|
| + const uint32_t mult = MULTIPLIER(a);
|
| + rgb[4 * i + 0] = PREMULTIPLY(rgb[4 * i + 0], mult);
|
| + rgb[4 * i + 1] = PREMULTIPLY(rgb[4 * i + 1], mult);
|
| + rgb[4 * i + 2] = PREMULTIPLY(rgb[4 * i + 2], mult);
|
| + }
|
| + }
|
| + rgba += stride;
|
| + }
|
| +}
|
| +#undef MULTIPLIER
|
| +#undef PREMULTIPLY
|
| +
|
| +// rgbA4444
|
| +
|
| +#define MULTIPLIER(a) ((a) * 0x11)
|
| +#define PREMULTIPLY(x, m) (((x) * (m)) >> 12)
|
| +
|
| +static WEBP_INLINE uint8_t dither_hi(uint8_t x) {
|
| + return (x & 0xf0) | (x >> 4);
|
| +}
|
| +
|
| +static WEBP_INLINE uint8_t dither_lo(uint8_t x) {
|
| + return (x & 0x0f) | (x << 4);
|
| +}
|
| +
|
| +static void ApplyAlphaMultiply4444(uint8_t* rgba4444,
|
| + int w, int h, int stride) {
|
| + while (h-- > 0) {
|
| + int i;
|
| + for (i = 0; i < w; ++i) {
|
| + const uint8_t a = dither_lo(rgba4444[2 * i + 1]);
|
| + const uint32_t mult = MULTIPLIER(a);
|
| + const uint8_t r = PREMULTIPLY(dither_hi(rgba4444[2 * i + 0]), mult);
|
| + const uint8_t g = PREMULTIPLY(dither_lo(rgba4444[2 * i + 0]), mult);
|
| + const uint8_t b = PREMULTIPLY(dither_hi(rgba4444[2 * i + 1]), mult);
|
| + rgba4444[2 * i + 0] = (r & 0xf0) | (g & 0x0f);
|
| + rgba4444[2 * i + 1] = (b & 0xf0) | a;
|
| + }
|
| + rgba4444 += stride;
|
| + }
|
| +}
|
| +#undef MULTIPLIER
|
| +#undef PREMULTIPLY
|
| +
|
| +void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int)
|
| + = ApplyAlphaMultiply;
|
| +void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int)
|
| + = ApplyAlphaMultiply4444;
|
| +
|
| +//------------------------------------------------------------------------------
|
| // Main call
|
|
|
| void WebPInitUpsamplers(void) {
|
| @@ -202,17 +319,9 @@ void WebPInitUpsamplers(void) {
|
| WebPUpsamplers[MODE_RGBA_4444] = UpsampleRgba4444LinePair;
|
| WebPUpsamplers[MODE_RGB_565] = UpsampleRgb565LinePair;
|
|
|
| - WebPUpsamplersKeepAlpha[MODE_RGB] = UpsampleRgbLinePair;
|
| - WebPUpsamplersKeepAlpha[MODE_RGBA] = UpsampleRgbKeepAlphaLinePair;
|
| - WebPUpsamplersKeepAlpha[MODE_BGR] = UpsampleBgrLinePair;
|
| - WebPUpsamplersKeepAlpha[MODE_BGRA] = UpsampleBgrKeepAlphaLinePair;
|
| - WebPUpsamplersKeepAlpha[MODE_ARGB] = UpsampleArgbKeepAlphaLinePair;
|
| - WebPUpsamplersKeepAlpha[MODE_RGBA_4444] = UpsampleRgba4444KeepAlphaLinePair;
|
| - WebPUpsamplersKeepAlpha[MODE_RGB_565] = UpsampleRgb565LinePair;
|
| -
|
| // If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
| - if (VP8GetCPUInfo) {
|
| -#if defined(__SSE2__) || defined(_MSC_VER)
|
| + if (VP8GetCPUInfo != NULL) {
|
| +#if defined(WEBP_USE_SSE2)
|
| if (VP8GetCPUInfo(kSSE2)) {
|
| WebPInitUpsamplersSSE2();
|
| }
|
| @@ -221,6 +330,26 @@ void WebPInitUpsamplers(void) {
|
| #endif // FANCY_UPSAMPLING
|
| }
|
|
|
| +void WebPInitPremultiply(void) {
|
| + WebPApplyAlphaMultiply = ApplyAlphaMultiply;
|
| + WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply4444;
|
| +
|
| +#ifdef FANCY_UPSAMPLING
|
| + WebPUpsamplers[MODE_rgbA] = UpsampleRgbaLinePair;
|
| + WebPUpsamplers[MODE_bgrA] = UpsampleBgraLinePair;
|
| + WebPUpsamplers[MODE_Argb] = UpsampleArgbLinePair;
|
| + WebPUpsamplers[MODE_rgbA_4444] = UpsampleRgba4444LinePair;
|
| +
|
| + if (VP8GetCPUInfo != NULL) {
|
| +#if defined(WEBP_USE_SSE2)
|
| + if (VP8GetCPUInfo(kSSE2)) {
|
| + WebPInitPremultiplySSE2();
|
| + }
|
| +#endif
|
| + }
|
| +#endif // FANCY_UPSAMPLING
|
| +}
|
| +
|
| #if defined(__cplusplus) || defined(c_plusplus)
|
| } // extern "C"
|
| #endif
|
|
|