diff --git a/src/dsp/dsp.h b/src/dsp/dsp.h index f8d13175..e611ccbe 100644 --- a/src/dsp/dsp.h +++ b/src/dsp/dsp.h @@ -325,7 +325,7 @@ void WebPInitSamplers(void); void WebPInitYUV444Converters(void); //------------------------------------------------------------------------------ -// ARGB -> YUV converters (for lossless decoding) +// ARGB -> YUV converters // Convert ARGB samples to luma Y. extern void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width); @@ -334,7 +334,12 @@ extern void (*WebPConvertARGBToY)(const uint32_t* argb, uint8_t* y, int width); // the U/V one. extern void (*WebPConvertARGBToUV)(const uint32_t* argb, uint8_t* u, uint8_t* v, int src_width, int do_store); -// Must be called before using WebPConvertARGBToXXX + +// Convert RGB or BGR to Y +extern void (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width); +extern void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, int width); + +// Must be called before using the above. void WebPInitConvertARGBToYUV(void); //------------------------------------------------------------------------------ diff --git a/src/dsp/yuv.c b/src/dsp/yuv.c index 2c1dbbee..5537204b 100644 --- a/src/dsp/yuv.c +++ b/src/dsp/yuv.c @@ -216,6 +216,27 @@ static void ConvertARGBToUV(const uint32_t* argb, uint8_t* u, uint8_t* v, } } +//----------------------------------------------------------------------------- + +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 (*WebPConvertRGB24ToY)(const uint8_t* rgb, uint8_t* y, int width); +void (*WebPConvertBGR24ToY)(const uint8_t* bgr, uint8_t* y, 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); @@ -228,6 +249,9 @@ WEBP_TSAN_IGNORE_FUNCTION void WebPInitConvertARGBToYUV(void) { WebPConvertARGBToY = ConvertARGBToY; WebPConvertARGBToUV = ConvertARGBToUV; + WebPConvertRGB24ToY = ConvertRGB24ToY; + WebPConvertBGR24ToY = ConvertBGR24ToY; + if (VP8GetCPUInfo != NULL) { #if defined(WEBP_USE_SSE2) if (VP8GetCPUInfo(kSSE2)) { diff --git a/src/enc/picture_csp.c b/src/enc/picture_csp.c index bef07aea..7fb898a4 100644 --- a/src/enc/picture_csp.c +++ b/src/enc/picture_csp.c @@ -885,6 +885,7 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr, picture->a, picture->a_stride); } } else { + int use_dsp = (step == 3); // use special function in this case uint8_t* dst_y = picture->y; uint8_t* dst_u = picture->u; uint8_t* dst_v = picture->v; @@ -895,7 +896,9 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr, if (dithering > 0.) { VP8InitRandom(&base_rg, dithering); rg = &base_rg; + use_dsp = 0; // can't use dsp in this case } + if (use_dsp) WebPInitConvertARGBToYUV(); InitGammaTables(); @@ -904,10 +907,20 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr, int rows_have_alpha = has_alpha; const int off1 = (2 * y + 0) * rgb_stride; const int off2 = (2 * y + 1) * rgb_stride; - ConvertRowToY(r_ptr + off1, g_ptr + off1, b_ptr + off1, step, - dst_y, width, rg); - ConvertRowToY(r_ptr + off2, g_ptr + off2, b_ptr + off2, step, - dst_y + picture->y_stride, width, rg); + if (use_dsp) { + if (r_ptr < b_ptr) { + WebPConvertRGB24ToY(r_ptr + off1, dst_y, width); + WebPConvertRGB24ToY(r_ptr + off2, dst_y + picture->y_stride, width); + } else { + WebPConvertBGR24ToY(b_ptr + off1, dst_y, width); + WebPConvertBGR24ToY(b_ptr + off2, dst_y + picture->y_stride, width); + } + } else { + ConvertRowToY(r_ptr + off1, g_ptr + off1, b_ptr + off1, step, + dst_y, width, rg); + ConvertRowToY(r_ptr + off2, g_ptr + off2, b_ptr + off2, step, + dst_y + picture->y_stride, width, rg); + } dst_y += 2 * picture->y_stride; if (has_alpha) { rows_have_alpha &= !WebPExtractAlpha(a_ptr + off1, rgb_stride, @@ -929,8 +942,16 @@ static int ImportYUVAFromRGBA(const uint8_t* const r_ptr, if (height & 1) { // extra last row const int off = 2 * y * rgb_stride; int row_has_alpha = has_alpha; - ConvertRowToY(r_ptr + off, g_ptr + off, b_ptr + off, step, - dst_y, width, rg); + if (use_dsp) { + if (r_ptr < b_ptr) { + WebPConvertRGB24ToY(r_ptr + off, dst_y, width); + } else { + WebPConvertBGR24ToY(b_ptr + off, dst_y, width); + } + } else { + ConvertRowToY(r_ptr + off, g_ptr + off, b_ptr + off, step, + dst_y, width, rg); + } if (row_has_alpha) { row_has_alpha &= !WebPExtractAlpha(a_ptr + off, 0, width, 1, dst_a, 0); }