| Index: third_party/libwebp/dsp/alpha_processing.c
|
| diff --git a/third_party/libwebp/utils/alpha_processing.c b/third_party/libwebp/dsp/alpha_processing.c
|
| similarity index 72%
|
| rename from third_party/libwebp/utils/alpha_processing.c
|
| rename to third_party/libwebp/dsp/alpha_processing.c
|
| index 7362ff94a54f3593c8ed67a0b635d0a070b9c81e..09deacfb9332869a0d4acc1489b8bc4624f0380d 100644
|
| --- a/third_party/libwebp/utils/alpha_processing.c
|
| +++ b/third_party/libwebp/dsp/alpha_processing.c
|
| @@ -12,7 +12,7 @@
|
| // Author: Skal (pascal.massimino@gmail.com)
|
|
|
| #include <assert.h>
|
| -#include "./alpha_processing.h"
|
| +#include "./dsp.h"
|
|
|
| // Tables can be faster on some platform but incur some extra binary size (~2k).
|
| // #define USE_TABLES_FOR_ALPHA_MULT
|
| @@ -134,7 +134,7 @@ static WEBP_INLINE uint32_t GetScale(uint32_t a, int inverse) {
|
|
|
| #endif // USE_TABLES_FOR_ALPHA_MULT
|
|
|
| -void WebPMultARGBRow(uint32_t* const ptr, int width, int inverse) {
|
| +static void MultARGBRow(uint32_t* const ptr, int width, int inverse) {
|
| int x;
|
| for (x = 0; x < width; ++x) {
|
| const uint32_t argb = ptr[x];
|
| @@ -154,17 +154,8 @@ void WebPMultARGBRow(uint32_t* const ptr, int width, int inverse) {
|
| }
|
| }
|
|
|
| -void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
|
| - int inverse) {
|
| - int n;
|
| - for (n = 0; n < num_rows; ++n) {
|
| - WebPMultARGBRow((uint32_t*)ptr, width, inverse);
|
| - ptr += stride;
|
| - }
|
| -}
|
| -
|
| -void WebPMultRow(uint8_t* const ptr, const uint8_t* const alpha,
|
| - int width, int inverse) {
|
| +static void MultRow(uint8_t* const ptr, const uint8_t* const alpha,
|
| + int width, int inverse) {
|
| int x;
|
| for (x = 0; x < width; ++x) {
|
| const uint32_t a = alpha[x];
|
| @@ -179,6 +170,26 @@ void WebPMultRow(uint8_t* const ptr, const uint8_t* const alpha,
|
| }
|
| }
|
|
|
| +#undef KINV_255
|
| +#undef HALF
|
| +#undef MFIX
|
| +
|
| +void (*WebPMultARGBRow)(uint32_t* const ptr, int width, int inverse);
|
| +void (*WebPMultRow)(uint8_t* const ptr, const uint8_t* const alpha,
|
| + int width, int inverse);
|
| +
|
| +//------------------------------------------------------------------------------
|
| +// Generic per-plane calls
|
| +
|
| +void WebPMultARGBRows(uint8_t* ptr, int stride, int width, int num_rows,
|
| + int inverse) {
|
| + int n;
|
| + for (n = 0; n < num_rows; ++n) {
|
| + WebPMultARGBRow((uint32_t*)ptr, width, inverse);
|
| + ptr += stride;
|
| + }
|
| +}
|
| +
|
| void WebPMultRows(uint8_t* ptr, int stride,
|
| const uint8_t* alpha, int alpha_stride,
|
| int width, int num_rows, int inverse) {
|
| @@ -190,7 +201,98 @@ void WebPMultRows(uint8_t* ptr, int stride,
|
| }
|
| }
|
|
|
| -#undef KINV_255
|
| -#undef HALF
|
| -#undef MFIX
|
| +//------------------------------------------------------------------------------
|
| +// 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) * 32897U)
|
| +#define PREMULTIPLY(x, m) (((x) * (m)) >> 23)
|
| +#else // (int)(x * a / 255. + .5)
|
| +#define MULTIPLIER(a) ((a) * 65793U)
|
| +#define PREMULTIPLY(x, m) (((x) * (m) + (1U << 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) * 0x1111) // 0x1111 ~= (1 << 16) / 15
|
| +
|
| +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 WEBP_INLINE uint8_t multiply(uint8_t x, uint32_t m) {
|
| + return (x * m) >> 16;
|
| +}
|
| +
|
| +static WEBP_INLINE void ApplyAlphaMultiply4444(uint8_t* rgba4444,
|
| + int w, int h, int stride,
|
| + int rg_byte_pos /* 0 or 1 */) {
|
| + while (h-- > 0) {
|
| + int i;
|
| + for (i = 0; i < w; ++i) {
|
| + const uint32_t rg = rgba4444[2 * i + rg_byte_pos];
|
| + const uint32_t ba = rgba4444[2 * i + (rg_byte_pos ^ 1)];
|
| + const uint8_t a = ba & 0x0f;
|
| + const uint32_t mult = MULTIPLIER(a);
|
| + const uint8_t r = multiply(dither_hi(rg), mult);
|
| + const uint8_t g = multiply(dither_lo(rg), mult);
|
| + const uint8_t b = multiply(dither_hi(ba), mult);
|
| + rgba4444[2 * i + rg_byte_pos] = (r & 0xf0) | ((g >> 4) & 0x0f);
|
| + rgba4444[2 * i + (rg_byte_pos ^ 1)] = (b & 0xf0) | a;
|
| + }
|
| + rgba4444 += stride;
|
| + }
|
| +}
|
| +#undef MULTIPLIER
|
|
|
| +static void ApplyAlphaMultiply_16b(uint8_t* rgba4444,
|
| + int w, int h, int stride) {
|
| +#ifdef WEBP_SWAP_16BIT_CSP
|
| + ApplyAlphaMultiply4444(rgba4444, w, h, stride, 1);
|
| +#else
|
| + ApplyAlphaMultiply4444(rgba4444, w, h, stride, 0);
|
| +#endif
|
| +}
|
| +
|
| +void (*WebPApplyAlphaMultiply)(uint8_t*, int, int, int, int);
|
| +void (*WebPApplyAlphaMultiply4444)(uint8_t*, int, int, int);
|
| +
|
| +//------------------------------------------------------------------------------
|
| +// Init function
|
| +
|
| +void WebPInitAlphaProcessing(void) {
|
| + WebPMultARGBRow = MultARGBRow;
|
| + WebPMultRow = MultRow;
|
| + WebPApplyAlphaMultiply = ApplyAlphaMultiply;
|
| + WebPApplyAlphaMultiply4444 = ApplyAlphaMultiply_16b;
|
| +}
|
|
|