| Index: third_party/libwebp/dsp/yuv.c
|
| diff --git a/third_party/libwebp/dsp/yuv.c b/third_party/libwebp/dsp/yuv.c
|
| index 6f422da532f76f55a51ce7d2cfeec269cde4f1df..f50a253168fee677de8effcd772d846cdeb3f3dd 100644
|
| --- a/third_party/libwebp/dsp/yuv.c
|
| +++ b/third_party/libwebp/dsp/yuv.c
|
| @@ -26,7 +26,7 @@ int32_t VP8kVToG[256], VP8kUToG[256];
|
| uint8_t VP8kClip[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
| uint8_t VP8kClip4Bits[YUV_RANGE_MAX - YUV_RANGE_MIN];
|
|
|
| -void VP8YUVInit(void) {
|
| +WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {
|
| int i;
|
| if (done) {
|
| return;
|
| @@ -62,7 +62,7 @@ void VP8YUVInit(void) {
|
|
|
| #else
|
|
|
| -void VP8YUVInit(void) {}
|
| +WEBP_TSAN_IGNORE_FUNCTION void VP8YUVInit(void) {}
|
|
|
| #endif // WEBP_YUV_USE_TABLE
|
|
|
| @@ -122,11 +122,12 @@ WebPSamplerRowFunc WebPSamplers[MODE_LAST];
|
|
|
| extern void WebPInitSamplersSSE2(void);
|
| extern void WebPInitSamplersMIPS32(void);
|
| +extern void WebPInitSamplersMIPSdspR2(void);
|
|
|
| static volatile VP8CPUInfo yuv_last_cpuinfo_used =
|
| (VP8CPUInfo)&yuv_last_cpuinfo_used;
|
|
|
| -void WebPInitSamplers(void) {
|
| +WEBP_TSAN_IGNORE_FUNCTION void WebPInitSamplers(void) {
|
| if (yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
|
|
|
| WebPSamplers[MODE_RGB] = YuvToRgbRow;
|
| @@ -153,8 +154,127 @@ void WebPInitSamplers(void) {
|
| WebPInitSamplersMIPS32();
|
| }
|
| #endif // WEBP_USE_MIPS32
|
| +#if defined(WEBP_USE_MIPS_DSP_R2)
|
| + if (VP8GetCPUInfo(kMIPSdspR2)) {
|
| + WebPInitSamplersMIPSdspR2();
|
| + }
|
| +#endif // WEBP_USE_MIPS_DSP_R2
|
| }
|
| yuv_last_cpuinfo_used = VP8GetCPUInfo;
|
| }
|
|
|
| //-----------------------------------------------------------------------------
|
| +// ARGB -> YUV converters
|
| +
|
| +static void ConvertARGBToY(const uint32_t* argb, uint8_t* y, int width) {
|
| + int i;
|
| + for (i = 0; i < width; ++i) {
|
| + const uint32_t p = argb[i];
|
| + y[i] = VP8RGBToY((p >> 16) & 0xff, (p >> 8) & 0xff, (p >> 0) & 0xff,
|
| + YUV_HALF);
|
| + }
|
| +}
|
| +
|
| +void WebPConvertARGBToUV_C(const uint32_t* argb, uint8_t* u, uint8_t* v,
|
| + int src_width, int do_store) {
|
| + // No rounding. Last pixel is dealt with separately.
|
| + const int uv_width = src_width >> 1;
|
| + int i;
|
| + for (i = 0; i < uv_width; ++i) {
|
| + const uint32_t v0 = argb[2 * i + 0];
|
| + const uint32_t v1 = argb[2 * i + 1];
|
| + // VP8RGBToU/V expects four accumulated pixels. Hence we need to
|
| + // scale r/g/b value by a factor 2. We just shift v0/v1 one bit less.
|
| + const int r = ((v0 >> 15) & 0x1fe) + ((v1 >> 15) & 0x1fe);
|
| + const int g = ((v0 >> 7) & 0x1fe) + ((v1 >> 7) & 0x1fe);
|
| + const int b = ((v0 << 1) & 0x1fe) + ((v1 << 1) & 0x1fe);
|
| + const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
|
| + const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
|
| + if (do_store) {
|
| + u[i] = tmp_u;
|
| + v[i] = tmp_v;
|
| + } else {
|
| + // Approximated average-of-four. But it's an acceptable diff.
|
| + u[i] = (u[i] + tmp_u + 1) >> 1;
|
| + v[i] = (v[i] + tmp_v + 1) >> 1;
|
| + }
|
| + }
|
| + if (src_width & 1) { // last pixel
|
| + const uint32_t v0 = argb[2 * i + 0];
|
| + const int r = (v0 >> 14) & 0x3fc;
|
| + const int g = (v0 >> 6) & 0x3fc;
|
| + const int b = (v0 << 2) & 0x3fc;
|
| + const int tmp_u = VP8RGBToU(r, g, b, YUV_HALF << 2);
|
| + const int tmp_v = VP8RGBToV(r, g, b, YUV_HALF << 2);
|
| + if (do_store) {
|
| + u[i] = tmp_u;
|
| + v[i] = tmp_v;
|
| + } else {
|
| + u[i] = (u[i] + tmp_u + 1) >> 1;
|
| + v[i] = (v[i] + tmp_v + 1) >> 1;
|
| + }
|
| + }
|
| +}
|
| +
|
| +//-----------------------------------------------------------------------------
|
| +
|
| +static void ConvertRGB24ToY(const uint8_t* rgb, uint8_t* y, int width) {
|
| + int i;
|
| + for (i = 0; i < width; ++i, rgb += 3) {
|
| + y[i] = VP8RGBToY(rgb[0], rgb[1], rgb[2], YUV_HALF);
|
| + }
|
| +}
|
| +
|
| +static void ConvertBGR24ToY(const uint8_t* bgr, uint8_t* y, int width) {
|
| + int i;
|
| + for (i = 0; i < width; ++i, bgr += 3) {
|
| + y[i] = VP8RGBToY(bgr[2], bgr[1], bgr[0], YUV_HALF);
|
| + }
|
| +}
|
| +
|
| +void WebPConvertRGBA32ToUV_C(const uint16_t* rgb,
|
| + uint8_t* u, uint8_t* v, int width) {
|
| + int i;
|
| + for (i = 0; i < width; i += 1, rgb += 4) {
|
| + const int r = rgb[0], g = rgb[1], b = rgb[2];
|
| + u[i] = VP8RGBToU(r, g, b, YUV_HALF << 2);
|
| + v[i] = VP8RGBToV(r, g, b, YUV_HALF << 2);
|
| + }
|
| +}
|
| +
|
| +//-----------------------------------------------------------------------------
|
| +
|
| +void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width);
|
| +void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width);
|
| +void (*WebPConvertRGBA32ToUV)(const uint16_t* rgb,
|
| + uint8_t* u, uint8_t* v, int width);
|
| +
|
| +void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width);
|
| +void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v,
|
| + int src_width, int do_store);
|
| +
|
| +static volatile VP8CPUInfo rgba_to_yuv_last_cpuinfo_used =
|
| + (VP8CPUInfo)&rgba_to_yuv_last_cpuinfo_used;
|
| +
|
| +extern void WebPInitConvertARGBToYUVSSE2(void);
|
| +
|
| +WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) {
|
| + if (rgba_to_yuv_last_cpuinfo_used == VP8GetCPUInfo) return;
|
| +
|
| + WebPConvertARGBToY = ConvertARGBToY;
|
| + WebPConvertARGBToUV = WebPConvertARGBToUV_C;
|
| +
|
| + WebPConvertRGB24ToY = ConvertRGB24ToY;
|
| + WebPConvertBGR24ToY = ConvertBGR24ToY;
|
| +
|
| + WebPConvertRGBA32ToUV = WebPConvertRGBA32ToUV_C;
|
| +
|
| + if (VP8GetCPUInfo != NULL) {
|
| +#if defined(WEBP_USE_SSE2)
|
| + if (VP8GetCPUInfo(kSSE2)) {
|
| + WebPInitConvertARGBToYUVSSE2();
|
| + }
|
| +#endif // WEBP_USE_SSE2
|
| + }
|
| + rgba_to_yuv_last_cpuinfo_used = VP8GetCPUInfo;
|
| +}
|
|
|