| Index: third_party/libwebp/dsp/dec.c
|
| diff --git a/third_party/libwebp/dsp/dec.c b/third_party/libwebp/dsp/dec.c
|
| index 3a8dc81ff4a0de67c0b5d8cc2f0000c65d02269f..a78720649b6d6b6265386eb0b1422d4a89b34db7 100644
|
| --- a/third_party/libwebp/dsp/dec.c
|
| +++ b/third_party/libwebp/dsp/dec.c
|
| @@ -7,7 +7,7 @@
|
| // be found in the AUTHORS file in the root of the source tree.
|
| // -----------------------------------------------------------------------------
|
| //
|
| -// Speed-critical decoding functions.
|
| +// Speed-critical decoding functions, default plain-C implementations.
|
| //
|
| // Author: Skal (pascal.massimino@gmail.com)
|
|
|
| @@ -34,9 +34,8 @@ static WEBP_INLINE uint8_t clip_8b(int v) {
|
| STORE(3, y, DC - (d)); \
|
| } while (0)
|
|
|
| -static const int kC1 = 20091 + (1 << 16);
|
| -static const int kC2 = 35468;
|
| -#define MUL(a, b) (((a) * (b)) >> 16)
|
| +#define MUL1(a) ((((a) * 20091) >> 16) + (a))
|
| +#define MUL2(a) (((a) * 35468) >> 16)
|
|
|
| static void TransformOne(const int16_t* in, uint8_t* dst) {
|
| int C[4 * 4], *tmp;
|
| @@ -45,8 +44,8 @@ static void TransformOne(const int16_t* in, uint8_t* dst) {
|
| for (i = 0; i < 4; ++i) { // vertical pass
|
| const int a = in[0] + in[8]; // [-4096, 4094]
|
| const int b = in[0] - in[8]; // [-4095, 4095]
|
| - const int c = MUL(in[4], kC2) - MUL(in[12], kC1); // [-3783, 3783]
|
| - const int d = MUL(in[4], kC1) + MUL(in[12], kC2); // [-3785, 3781]
|
| + const int c = MUL2(in[4]) - MUL1(in[12]); // [-3783, 3783]
|
| + const int d = MUL1(in[4]) + MUL2(in[12]); // [-3785, 3781]
|
| tmp[0] = a + d; // [-7881, 7875]
|
| tmp[1] = b + c; // [-7878, 7878]
|
| tmp[2] = b - c; // [-7878, 7878]
|
| @@ -55,7 +54,7 @@ static void TransformOne(const int16_t* in, uint8_t* dst) {
|
| in++;
|
| }
|
| // Each pass is expanding the dynamic range by ~3.85 (upper bound).
|
| - // The exact value is (2. + (kC1 + kC2) / 65536).
|
| + // The exact value is (2. + (20091 + 35468) / 65536).
|
| // After the second pass, maximum interval is [-3794, 3794], assuming
|
| // an input in [-2048, 2047] interval. We then need to add a dst value
|
| // in the [0, 255] range.
|
| @@ -66,8 +65,8 @@ static void TransformOne(const int16_t* in, uint8_t* dst) {
|
| const int dc = tmp[0] + 4;
|
| const int a = dc + tmp[8];
|
| const int b = dc - tmp[8];
|
| - const int c = MUL(tmp[4], kC2) - MUL(tmp[12], kC1);
|
| - const int d = MUL(tmp[4], kC1) + MUL(tmp[12], kC2);
|
| + const int c = MUL2(tmp[4]) - MUL1(tmp[12]);
|
| + const int d = MUL1(tmp[4]) + MUL2(tmp[12]);
|
| STORE(0, 0, a + d);
|
| STORE(1, 0, b + c);
|
| STORE(2, 0, b - c);
|
| @@ -80,16 +79,17 @@ static void TransformOne(const int16_t* in, uint8_t* dst) {
|
| // Simplified transform when only in[0], in[1] and in[4] are non-zero
|
| static void TransformAC3(const int16_t* in, uint8_t* dst) {
|
| const int a = in[0] + 4;
|
| - const int c4 = MUL(in[4], kC2);
|
| - const int d4 = MUL(in[4], kC1);
|
| - const int c1 = MUL(in[1], kC2);
|
| - const int d1 = MUL(in[1], kC1);
|
| + const int c4 = MUL2(in[4]);
|
| + const int d4 = MUL1(in[4]);
|
| + const int c1 = MUL2(in[1]);
|
| + const int d1 = MUL1(in[1]);
|
| STORE2(0, a + d4, d1, c1);
|
| STORE2(1, a + c4, d1, c1);
|
| STORE2(2, a - c4, d1, c1);
|
| STORE2(3, a - d4, d1, c1);
|
| }
|
| -#undef MUL
|
| +#undef MUL1
|
| +#undef MUL2
|
| #undef STORE2
|
|
|
| static void TransformTwo(const int16_t* in, uint8_t* dst, int do_two) {
|
| @@ -104,7 +104,7 @@ static void TransformUV(const int16_t* in, uint8_t* dst) {
|
| VP8Transform(in + 2 * 16, dst + 4 * BPS, 1);
|
| }
|
|
|
| -static void TransformDC(const int16_t *in, uint8_t* dst) {
|
| +static void TransformDC(const int16_t* in, uint8_t* dst) {
|
| const int DC = in[0] + 4;
|
| int i, j;
|
| for (j = 0; j < 4; ++j) {
|
| @@ -160,7 +160,7 @@ void (*VP8TransformWHT)(const int16_t* in, int16_t* out);
|
|
|
| #define DST(x, y) dst[(x) + (y) * BPS]
|
|
|
| -static WEBP_INLINE void TrueMotion(uint8_t *dst, int size) {
|
| +static WEBP_INLINE void TrueMotion(uint8_t* dst, int size) {
|
| const uint8_t* top = dst - BPS;
|
| const uint8_t* const clip0 = VP8kclip1 - top[-1];
|
| int y;
|
| @@ -173,21 +173,21 @@ static WEBP_INLINE void TrueMotion(uint8_t *dst, int size) {
|
| dst += BPS;
|
| }
|
| }
|
| -static void TM4(uint8_t *dst) { TrueMotion(dst, 4); }
|
| -static void TM8uv(uint8_t *dst) { TrueMotion(dst, 8); }
|
| -static void TM16(uint8_t *dst) { TrueMotion(dst, 16); }
|
| +static void TM4(uint8_t* dst) { TrueMotion(dst, 4); }
|
| +static void TM8uv(uint8_t* dst) { TrueMotion(dst, 8); }
|
| +static void TM16(uint8_t* dst) { TrueMotion(dst, 16); }
|
|
|
| //------------------------------------------------------------------------------
|
| // 16x16
|
|
|
| -static void VE16(uint8_t *dst) { // vertical
|
| +static void VE16(uint8_t* dst) { // vertical
|
| int j;
|
| for (j = 0; j < 16; ++j) {
|
| memcpy(dst + j * BPS, dst - BPS, 16);
|
| }
|
| }
|
|
|
| -static void HE16(uint8_t *dst) { // horizontal
|
| +static void HE16(uint8_t* dst) { // horizontal
|
| int j;
|
| for (j = 16; j > 0; --j) {
|
| memset(dst, dst[-1], 16);
|
| @@ -202,7 +202,7 @@ static WEBP_INLINE void Put16(int v, uint8_t* dst) {
|
| }
|
| }
|
|
|
| -static void DC16(uint8_t *dst) { // DC
|
| +static void DC16(uint8_t* dst) { // DC
|
| int DC = 16;
|
| int j;
|
| for (j = 0; j < 16; ++j) {
|
| @@ -211,7 +211,7 @@ static void DC16(uint8_t *dst) { // DC
|
| Put16(DC >> 5, dst);
|
| }
|
|
|
| -static void DC16NoTop(uint8_t *dst) { // DC with top samples not available
|
| +static void DC16NoTop(uint8_t* dst) { // DC with top samples not available
|
| int DC = 8;
|
| int j;
|
| for (j = 0; j < 16; ++j) {
|
| @@ -220,7 +220,7 @@ static void DC16NoTop(uint8_t *dst) { // DC with top samples not available
|
| Put16(DC >> 4, dst);
|
| }
|
|
|
| -static void DC16NoLeft(uint8_t *dst) { // DC with left samples not available
|
| +static void DC16NoLeft(uint8_t* dst) { // DC with left samples not available
|
| int DC = 8;
|
| int i;
|
| for (i = 0; i < 16; ++i) {
|
| @@ -229,17 +229,19 @@ static void DC16NoLeft(uint8_t *dst) { // DC with left samples not available
|
| Put16(DC >> 4, dst);
|
| }
|
|
|
| -static void DC16NoTopLeft(uint8_t *dst) { // DC with no top and left samples
|
| +static void DC16NoTopLeft(uint8_t* dst) { // DC with no top and left samples
|
| Put16(0x80, dst);
|
| }
|
|
|
| +VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES];
|
| +
|
| //------------------------------------------------------------------------------
|
| // 4x4
|
|
|
| #define AVG3(a, b, c) (((a) + 2 * (b) + (c) + 2) >> 2)
|
| #define AVG2(a, b) (((a) + (b) + 1) >> 1)
|
|
|
| -static void VE4(uint8_t *dst) { // vertical
|
| +static void VE4(uint8_t* dst) { // vertical
|
| const uint8_t* top = dst - BPS;
|
| const uint8_t vals[4] = {
|
| AVG3(top[-1], top[0], top[1]),
|
| @@ -253,19 +255,19 @@ static void VE4(uint8_t *dst) { // vertical
|
| }
|
| }
|
|
|
| -static void HE4(uint8_t *dst) { // horizontal
|
| +static void HE4(uint8_t* dst) { // horizontal
|
| const int A = dst[-1 - BPS];
|
| const int B = dst[-1];
|
| const int C = dst[-1 + BPS];
|
| const int D = dst[-1 + 2 * BPS];
|
| const int E = dst[-1 + 3 * BPS];
|
| - *(uint32_t*)(dst + 0 * BPS) = 0x01010101U * AVG3(A, B, C);
|
| - *(uint32_t*)(dst + 1 * BPS) = 0x01010101U * AVG3(B, C, D);
|
| - *(uint32_t*)(dst + 2 * BPS) = 0x01010101U * AVG3(C, D, E);
|
| - *(uint32_t*)(dst + 3 * BPS) = 0x01010101U * AVG3(D, E, E);
|
| + WebPUint32ToMem(dst + 0 * BPS, 0x01010101U * AVG3(A, B, C));
|
| + WebPUint32ToMem(dst + 1 * BPS, 0x01010101U * AVG3(B, C, D));
|
| + WebPUint32ToMem(dst + 2 * BPS, 0x01010101U * AVG3(C, D, E));
|
| + WebPUint32ToMem(dst + 3 * BPS, 0x01010101U * AVG3(D, E, E));
|
| }
|
|
|
| -static void DC4(uint8_t *dst) { // DC
|
| +static void DC4(uint8_t* dst) { // DC
|
| uint32_t dc = 4;
|
| int i;
|
| for (i = 0; i < 4; ++i) dc += dst[i - BPS] + dst[-1 + i * BPS];
|
| @@ -273,7 +275,7 @@ static void DC4(uint8_t *dst) { // DC
|
| for (i = 0; i < 4; ++i) memset(dst + i * BPS, dc, 4);
|
| }
|
|
|
| -static void RD4(uint8_t *dst) { // Down-right
|
| +static void RD4(uint8_t* dst) { // Down-right
|
| const int I = dst[-1 + 0 * BPS];
|
| const int J = dst[-1 + 1 * BPS];
|
| const int K = dst[-1 + 2 * BPS];
|
| @@ -284,15 +286,15 @@ static void RD4(uint8_t *dst) { // Down-right
|
| const int C = dst[2 - BPS];
|
| const int D = dst[3 - BPS];
|
| DST(0, 3) = AVG3(J, K, L);
|
| - DST(0, 2) = DST(1, 3) = AVG3(I, J, K);
|
| - DST(0, 1) = DST(1, 2) = DST(2, 3) = AVG3(X, I, J);
|
| - DST(0, 0) = DST(1, 1) = DST(2, 2) = DST(3, 3) = AVG3(A, X, I);
|
| - DST(1, 0) = DST(2, 1) = DST(3, 2) = AVG3(B, A, X);
|
| - DST(2, 0) = DST(3, 1) = AVG3(C, B, A);
|
| - DST(3, 0) = AVG3(D, C, B);
|
| + DST(1, 3) = DST(0, 2) = AVG3(I, J, K);
|
| + DST(2, 3) = DST(1, 2) = DST(0, 1) = AVG3(X, I, J);
|
| + DST(3, 3) = DST(2, 2) = DST(1, 1) = DST(0, 0) = AVG3(A, X, I);
|
| + DST(3, 2) = DST(2, 1) = DST(1, 0) = AVG3(B, A, X);
|
| + DST(3, 1) = DST(2, 0) = AVG3(C, B, A);
|
| + DST(3, 0) = AVG3(D, C, B);
|
| }
|
|
|
| -static void LD4(uint8_t *dst) { // Down-Left
|
| +static void LD4(uint8_t* dst) { // Down-Left
|
| const int A = dst[0 - BPS];
|
| const int B = dst[1 - BPS];
|
| const int C = dst[2 - BPS];
|
| @@ -305,12 +307,12 @@ static void LD4(uint8_t *dst) { // Down-Left
|
| DST(1, 0) = DST(0, 1) = AVG3(B, C, D);
|
| DST(2, 0) = DST(1, 1) = DST(0, 2) = AVG3(C, D, E);
|
| DST(3, 0) = DST(2, 1) = DST(1, 2) = DST(0, 3) = AVG3(D, E, F);
|
| - DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
|
| - DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
|
| - DST(3, 3) = AVG3(G, H, H);
|
| + DST(3, 1) = DST(2, 2) = DST(1, 3) = AVG3(E, F, G);
|
| + DST(3, 2) = DST(2, 3) = AVG3(F, G, H);
|
| + DST(3, 3) = AVG3(G, H, H);
|
| }
|
|
|
| -static void VR4(uint8_t *dst) { // Vertical-Right
|
| +static void VR4(uint8_t* dst) { // Vertical-Right
|
| const int I = dst[-1 + 0 * BPS];
|
| const int J = dst[-1 + 1 * BPS];
|
| const int K = dst[-1 + 2 * BPS];
|
| @@ -332,7 +334,7 @@ static void VR4(uint8_t *dst) { // Vertical-Right
|
| DST(3, 1) = AVG3(B, C, D);
|
| }
|
|
|
| -static void VL4(uint8_t *dst) { // Vertical-Left
|
| +static void VL4(uint8_t* dst) { // Vertical-Left
|
| const int A = dst[0 - BPS];
|
| const int B = dst[1 - BPS];
|
| const int C = dst[2 - BPS];
|
| @@ -354,7 +356,7 @@ static void VL4(uint8_t *dst) { // Vertical-Left
|
| DST(3, 3) = AVG3(F, G, H);
|
| }
|
|
|
| -static void HU4(uint8_t *dst) { // Horizontal-Up
|
| +static void HU4(uint8_t* dst) { // Horizontal-Up
|
| const int I = dst[-1 + 0 * BPS];
|
| const int J = dst[-1 + 1 * BPS];
|
| const int K = dst[-1 + 2 * BPS];
|
| @@ -369,7 +371,7 @@ static void HU4(uint8_t *dst) { // Horizontal-Up
|
| DST(0, 3) = DST(1, 3) = DST(2, 3) = DST(3, 3) = L;
|
| }
|
|
|
| -static void HD4(uint8_t *dst) { // Horizontal-Down
|
| +static void HD4(uint8_t* dst) { // Horizontal-Down
|
| const int I = dst[-1 + 0 * BPS];
|
| const int J = dst[-1 + 1 * BPS];
|
| const int K = dst[-1 + 2 * BPS];
|
| @@ -396,17 +398,19 @@ static void HD4(uint8_t *dst) { // Horizontal-Down
|
| #undef AVG3
|
| #undef AVG2
|
|
|
| +VP8PredFunc VP8PredLuma4[NUM_BMODES];
|
| +
|
| //------------------------------------------------------------------------------
|
| // Chroma
|
|
|
| -static void VE8uv(uint8_t *dst) { // vertical
|
| +static void VE8uv(uint8_t* dst) { // vertical
|
| int j;
|
| for (j = 0; j < 8; ++j) {
|
| memcpy(dst + j * BPS, dst - BPS, 8);
|
| }
|
| }
|
|
|
| -static void HE8uv(uint8_t *dst) { // horizontal
|
| +static void HE8uv(uint8_t* dst) { // horizontal
|
| int j;
|
| for (j = 0; j < 8; ++j) {
|
| memset(dst, dst[-1], 8);
|
| @@ -422,7 +426,7 @@ static WEBP_INLINE void Put8x8uv(uint8_t value, uint8_t* dst) {
|
| }
|
| }
|
|
|
| -static void DC8uv(uint8_t *dst) { // DC
|
| +static void DC8uv(uint8_t* dst) { // DC
|
| int dc0 = 8;
|
| int i;
|
| for (i = 0; i < 8; ++i) {
|
| @@ -431,7 +435,7 @@ static void DC8uv(uint8_t *dst) { // DC
|
| Put8x8uv(dc0 >> 4, dst);
|
| }
|
|
|
| -static void DC8uvNoLeft(uint8_t *dst) { // DC with no left samples
|
| +static void DC8uvNoLeft(uint8_t* dst) { // DC with no left samples
|
| int dc0 = 4;
|
| int i;
|
| for (i = 0; i < 8; ++i) {
|
| @@ -440,7 +444,7 @@ static void DC8uvNoLeft(uint8_t *dst) { // DC with no left samples
|
| Put8x8uv(dc0 >> 3, dst);
|
| }
|
|
|
| -static void DC8uvNoTop(uint8_t *dst) { // DC with no top samples
|
| +static void DC8uvNoTop(uint8_t* dst) { // DC with no top samples
|
| int dc0 = 4;
|
| int i;
|
| for (i = 0; i < 8; ++i) {
|
| @@ -449,26 +453,11 @@ static void DC8uvNoTop(uint8_t *dst) { // DC with no top samples
|
| Put8x8uv(dc0 >> 3, dst);
|
| }
|
|
|
| -static void DC8uvNoTopLeft(uint8_t *dst) { // DC with nothing
|
| +static void DC8uvNoTopLeft(uint8_t* dst) { // DC with nothing
|
| Put8x8uv(0x80, dst);
|
| }
|
|
|
| -//------------------------------------------------------------------------------
|
| -// default C implementations
|
| -
|
| -const VP8PredFunc VP8PredLuma4[NUM_BMODES] = {
|
| - DC4, TM4, VE4, HE4, RD4, VR4, LD4, VL4, HD4, HU4
|
| -};
|
| -
|
| -const VP8PredFunc VP8PredLuma16[NUM_B_DC_MODES] = {
|
| - DC16, TM16, VE16, HE16,
|
| - DC16NoTop, DC16NoLeft, DC16NoTopLeft
|
| -};
|
| -
|
| -const VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES] = {
|
| - DC8uv, TM8uv, VE8uv, HE8uv,
|
| - DC8uvNoTop, DC8uvNoLeft, DC8uvNoTopLeft
|
| -};
|
| +VP8PredFunc VP8PredChroma8[NUM_B_DC_MODES];
|
|
|
| //------------------------------------------------------------------------------
|
| // Edge filtering functions
|
| @@ -685,13 +674,15 @@ VP8SimpleFilterFunc VP8SimpleVFilter16i;
|
| VP8SimpleFilterFunc VP8SimpleHFilter16i;
|
|
|
| extern void VP8DspInitSSE2(void);
|
| +extern void VP8DspInitSSE41(void);
|
| extern void VP8DspInitNEON(void);
|
| extern void VP8DspInitMIPS32(void);
|
| +extern void VP8DspInitMIPSdspR2(void);
|
|
|
| static volatile VP8CPUInfo dec_last_cpuinfo_used =
|
| (VP8CPUInfo)&dec_last_cpuinfo_used;
|
|
|
| -void VP8DspInit(void) {
|
| +WEBP_TSAN_IGNORE_FUNCTION void VP8DspInit(void) {
|
| if (dec_last_cpuinfo_used == VP8GetCPUInfo) return;
|
|
|
| VP8InitClipTables();
|
| @@ -716,21 +707,60 @@ void VP8DspInit(void) {
|
| VP8SimpleVFilter16i = SimpleVFilter16i;
|
| VP8SimpleHFilter16i = SimpleHFilter16i;
|
|
|
| + VP8PredLuma4[0] = DC4;
|
| + VP8PredLuma4[1] = TM4;
|
| + VP8PredLuma4[2] = VE4;
|
| + VP8PredLuma4[3] = HE4;
|
| + VP8PredLuma4[4] = RD4;
|
| + VP8PredLuma4[5] = VR4;
|
| + VP8PredLuma4[6] = LD4;
|
| + VP8PredLuma4[7] = VL4;
|
| + VP8PredLuma4[8] = HD4;
|
| + VP8PredLuma4[9] = HU4;
|
| +
|
| + VP8PredLuma16[0] = DC16;
|
| + VP8PredLuma16[1] = TM16;
|
| + VP8PredLuma16[2] = VE16;
|
| + VP8PredLuma16[3] = HE16;
|
| + VP8PredLuma16[4] = DC16NoTop;
|
| + VP8PredLuma16[5] = DC16NoLeft;
|
| + VP8PredLuma16[6] = DC16NoTopLeft;
|
| +
|
| + VP8PredChroma8[0] = DC8uv;
|
| + VP8PredChroma8[1] = TM8uv;
|
| + VP8PredChroma8[2] = VE8uv;
|
| + VP8PredChroma8[3] = HE8uv;
|
| + VP8PredChroma8[4] = DC8uvNoTop;
|
| + VP8PredChroma8[5] = DC8uvNoLeft;
|
| + VP8PredChroma8[6] = DC8uvNoTopLeft;
|
| +
|
| // If defined, use CPUInfo() to overwrite some pointers with faster versions.
|
| if (VP8GetCPUInfo != NULL) {
|
| #if defined(WEBP_USE_SSE2)
|
| if (VP8GetCPUInfo(kSSE2)) {
|
| VP8DspInitSSE2();
|
| +#if defined(WEBP_USE_SSE41)
|
| + if (VP8GetCPUInfo(kSSE4_1)) {
|
| + VP8DspInitSSE41();
|
| + }
|
| +#endif
|
| }
|
| -#elif defined(WEBP_USE_NEON)
|
| +#endif
|
| +#if defined(WEBP_USE_NEON)
|
| if (VP8GetCPUInfo(kNEON)) {
|
| VP8DspInitNEON();
|
| }
|
| -#elif defined(WEBP_USE_MIPS32)
|
| +#endif
|
| +#if defined(WEBP_USE_MIPS32)
|
| if (VP8GetCPUInfo(kMIPS32)) {
|
| VP8DspInitMIPS32();
|
| }
|
| #endif
|
| +#if defined(WEBP_USE_MIPS_DSP_R2)
|
| + if (VP8GetCPUInfo(kMIPSdspR2)) {
|
| + VP8DspInitMIPSdspR2();
|
| + }
|
| +#endif
|
| }
|
| dec_last_cpuinfo_used = VP8GetCPUInfo;
|
| }
|
|
|