diff --git a/src/dec/io.c b/src/dec/io.c index e461da8c..5f4bed76 100644 --- a/src/dec/io.c +++ b/src/dec/io.c @@ -119,7 +119,7 @@ static int EmitFancyRGB(const VP8Io* const io, WebPDecParams* const p) { if (y == 0) { // First line is special cased. We mirror the u/v samples at boundary. - upsample(NULL, cur_y, cur_u, cur_v, cur_u, cur_v, NULL, dst, mb_w); + upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, mb_w); } else { // We can finish the left-over line from previous call. upsample(p->tmp_y, cur_y, top_u, top_v, cur_u, cur_v, diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h index 01a95891..d8bf07e3 100644 --- a/src/dsp/dsp.h +++ b/src/dsp/dsp.h @@ -146,6 +146,8 @@ void VP8DspInit(void); #define FANCY_UPSAMPLING // undefined to remove fancy upsampling support +// Convert a pair of y/u/v lines together to the output rgb/a colorspace. +// bottom_y can be NULL if only one line of output is needed (at top/bottom). typedef void (*WebPUpsampleLinePairFunc)( const uint8_t* top_y, const uint8_t* bottom_y, const uint8_t* top_u, const uint8_t* top_v, diff --git a/src/dsp/upsampling.c b/src/dsp/upsampling.c index 80ba4f8a..42625412 100644 --- a/src/dsp/upsampling.c +++ b/src/dsp/upsampling.c @@ -18,6 +18,8 @@ extern "C" { #endif +#include + //------------------------------------------------------------------------------ // Fancy upsampler @@ -45,11 +47,12 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ const int last_pixel_pair = (len - 1) >> 1; \ uint32_t tl_uv = LOAD_UV(top_u[0], top_v[0]); /* top-left sample */ \ uint32_t l_uv = LOAD_UV(cur_u[0], cur_v[0]); /* left-sample */ \ - if (top_y) { \ + assert(top_y != NULL); \ + { \ const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ FUNC(top_y[0], uv0 & 0xff, (uv0 >> 16), top_dst); \ } \ - if (bottom_y) { \ + if (bottom_y != NULL) { \ const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ FUNC(bottom_y[0], uv0 & 0xff, (uv0 >> 16), bottom_dst); \ } \ @@ -60,7 +63,7 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ const uint32_t avg = tl_uv + t_uv + l_uv + uv + 0x00080008u; \ const uint32_t diag_12 = (avg + 2 * (t_uv + l_uv)) >> 3; \ const uint32_t diag_03 = (avg + 2 * (tl_uv + uv)) >> 3; \ - if (top_y) { \ + { \ const uint32_t uv0 = (diag_12 + tl_uv) >> 1; \ const uint32_t uv1 = (diag_03 + t_uv) >> 1; \ FUNC(top_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ @@ -68,7 +71,7 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ FUNC(top_y[2 * x - 0], uv1 & 0xff, (uv1 >> 16), \ top_dst + (2 * x - 0) * XSTEP); \ } \ - if (bottom_y) { \ + if (bottom_y != NULL) { \ const uint32_t uv0 = (diag_03 + l_uv) >> 1; \ const uint32_t uv1 = (diag_12 + uv) >> 1; \ FUNC(bottom_y[2 * x - 1], uv0 & 0xff, (uv0 >> 16), \ @@ -80,12 +83,12 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ l_uv = uv; \ } \ if (!(len & 1)) { \ - if (top_y) { \ + { \ const uint32_t uv0 = (3 * tl_uv + l_uv + 0x00020002u) >> 2; \ FUNC(top_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ top_dst + (len - 1) * XSTEP); \ } \ - if (bottom_y) { \ + if (bottom_y != NULL) { \ const uint32_t uv0 = (3 * l_uv + tl_uv + 0x00020002u) >> 2; \ FUNC(bottom_y[len - 1], uv0 & 0xff, (uv0 >> 16), \ bottom_dst + (len - 1) * XSTEP); \ @@ -168,7 +171,8 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bot_y, \ uint8_t* top_dst, uint8_t* bot_dst, int len) { \ const int half_len = len >> 1; \ int x; \ - if (top_dst != NULL) { \ + assert(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); \ diff --git a/src/dsp/upsampling_neon.c b/src/dsp/upsampling_neon.c index d1188959..0b64ed86 100644 --- a/src/dsp/upsampling_neon.c +++ b/src/dsp/upsampling_neon.c @@ -189,20 +189,16 @@ static const int16_t coef[4] = { CVR / 4, CUG, CVG / 2, CUB / 4 }; #define CONVERT2RGB_8(FMT, XSTEP, top_y, bottom_y, uv, \ top_dst, bottom_dst, cur_x, len) { \ - if (top_y) { \ - CONVERT8(FMT, XSTEP, len, top_y, uv, top_dst, cur_x) \ - } \ - if (bottom_y) { \ + CONVERT8(FMT, XSTEP, len, top_y, uv, top_dst, cur_x) \ + if (bottom_y != NULL) { \ CONVERT8(FMT, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x) \ } \ } #define CONVERT2RGB_1(FMT, XSTEP, top_y, bottom_y, uv, \ top_dst, bottom_dst, cur_x, len) { \ - if (top_y) { \ - CONVERT1(FMT, XSTEP, len, top_y, uv, top_dst, cur_x); \ - } \ - if (bottom_y) { \ + CONVERT1(FMT, XSTEP, len, top_y, uv, top_dst, cur_x); \ + if (bottom_y != NULL) { \ CONVERT1(FMT, XSTEP, len, bottom_y, (uv) + 32, bottom_dst, cur_x); \ } \ } @@ -231,12 +227,13 @@ static void FUNC_NAME(const uint8_t *top_y, const uint8_t *bottom_y, \ const uint8x8_t u128 = vmov_n_u8(128); \ \ /* Treat the first pixel in regular way */ \ - if (top_y) { \ + assert(top_y != NULL); \ + { \ const int u0 = (top_u[0] + u_diag) >> 1; \ const int v0 = (top_v[0] + v_diag) >> 1; \ VP8YuvTo ## FMT(top_y[0], u0, v0, top_dst); \ } \ - if (bottom_y) { \ + if (bottom_y != NULL) { \ const int u0 = (cur_u[0] + u_diag) >> 1; \ const int v0 = (cur_v[0] + v_diag) >> 1; \ VP8YuvTo ## FMT(bottom_y[0], u0, v0, bottom_dst); \ @@ -271,6 +268,8 @@ NEON_UPSAMPLE_FUNC(UpsampleBgraLinePairNEON, Bgra, 4) //------------------------------------------------------------------------------ +#ifdef FANCY_UPSAMPLING + extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */]; void WebPInitUpsamplersNEON(void) { @@ -289,6 +288,14 @@ void WebPInitPremultiplyNEON(void) { #endif // WEBP_USE_NEON } +#else + +// this empty function is to avoid an empty .o +void WebPInitPremultiplyNEON(void) {} + +#endif // FANCY_UPSAMPLING + + #if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif diff --git a/src/dsp/upsampling_sse2.c b/src/dsp/upsampling_sse2.c index f31d0484..d2a1b535 100644 --- a/src/dsp/upsampling_sse2.c +++ b/src/dsp/upsampling_sse2.c @@ -111,13 +111,11 @@ static void Upsample32Pixels(const uint8_t r1[], const uint8_t r2[], #define CONVERT2RGB(FUNC, XSTEP, top_y, bottom_y, uv, \ 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], (uv)[n], (uv)[32 + 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], \ bottom_dst + ((cur_x) + n) * XSTEP); \ @@ -145,12 +143,13 @@ static void FUNC_NAME(const uint8_t* top_y, const uint8_t* bottom_y, \ \ assert(len > 0); \ /* Treat the first pixel in regular way */ \ - if (top_y) { \ + assert(top_y != NULL); \ + { \ 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); \ } \ - if (bottom_y) { \ + if (bottom_y != NULL) { \ 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); \ @@ -192,6 +191,8 @@ SSE2_UPSAMPLE_FUNC(UpsampleBgraLinePairSSE2, VP8YuvToBgra, 4) //------------------------------------------------------------------------------ +#ifdef FANCY_UPSAMPLING + extern WebPUpsampleLinePairFunc WebPUpsamplers[/* MODE_LAST */]; void WebPInitUpsamplersSSE2(void) { @@ -210,8 +211,13 @@ void WebPInitPremultiplySSE2(void) { #endif // WEBP_USE_SSE2 } +#else + +// this empty function is to avoid an empty .o +void WebPInitPremultiplySSE2(void); + +#endif // FANCY_UPSAMPLING + #if defined(__cplusplus) || defined(c_plusplus) } // extern "C" #endif - - diff --git a/src/enc/picture.c b/src/enc/picture.c index 5f40b33d..a53990eb 100644 --- a/src/enc/picture.c +++ b/src/enc/picture.c @@ -820,7 +820,7 @@ int WebPPictureYUVAToARGB(WebPPicture* picture) { WebPUpsampleLinePairFunc upsample = WebPGetLinePairConverter(ALPHA_IS_LAST); // First row, with replicated top samples. - upsample(NULL, cur_y, cur_u, cur_v, cur_u, cur_v, NULL, dst, width); + upsample(cur_y, NULL, cur_u, cur_v, cur_u, cur_v, dst, NULL, width); cur_y += picture->y_stride; dst += argb_stride; // Center rows.