diff --git a/include/libyuv/convert_argb.h b/include/libyuv/convert_argb.h index ced3c68b1..873156fc1 100644 --- a/include/libyuv/convert_argb.h +++ b/include/libyuv/convert_argb.h @@ -530,6 +530,15 @@ int AR30ToARGB(const uint8_t* src_ar30, int width, int height); +// Convert AR30 To ABGR. +LIBYUV_API +int AR30ToABGR(const uint8_t* src_ar30, + int src_stride_ar30, + uint8_t* dst_abgr, + int dst_stride_abgr, + int width, + int height); + #ifdef HAVE_JPEG // src_width/height provided by capture // dst_width/height for clipping determine final size. diff --git a/include/libyuv/row.h b/include/libyuv/row.h index c70928e1e..9cf711e27 100644 --- a/include/libyuv/row.h +++ b/include/libyuv/row.h @@ -1613,6 +1613,7 @@ void RGB565ToARGBRow_C(const uint8_t* src_rgb, uint8_t* dst_argb, int width); void ARGB1555ToARGBRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width); void ARGB4444ToARGBRow_C(const uint8_t* src_argb, uint8_t* dst_argb, int width); void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width); +void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width); void RGB24ToARGBRow_Any_SSSE3(const uint8_t* src_rgb24, uint8_t* dst_argb, int width); diff --git a/source/convert_argb.cc b/source/convert_argb.cc index 94240f296..bea04e4c5 100644 --- a/source/convert_argb.cc +++ b/source/convert_argb.cc @@ -1445,8 +1445,6 @@ int AR30ToARGB(const uint8_t* src_ar30, int width, int height) { int y; - void (*AR30ToARGBRow)(const uint8_t* src_ar30, uint8_t* dst_argb, int width) = - AR30ToARGBRow_C; if (!src_ar30 || !dst_argb || width <= 0 || height == 0) { return -1; } @@ -1463,13 +1461,45 @@ int AR30ToARGB(const uint8_t* src_ar30, src_stride_ar30 = dst_stride_argb = 0; } for (y = 0; y < height; ++y) { - AR30ToARGBRow(src_ar30, dst_argb, width); + AR30ToARGBRow_C(src_ar30, dst_argb, width); src_ar30 += src_stride_ar30; dst_argb += dst_stride_argb; } return 0; } +// Convert AR30 to ABGR. +LIBYUV_API +int AR30ToABGR(const uint8_t* src_ar30, + int src_stride_ar30, + uint8_t* dst_abgr, + int dst_stride_abgr, + int width, + int height) { + int y; + if (!src_ar30 || !dst_abgr || width <= 0 || height == 0) { + return -1; + } + // Negative height means invert the image. + if (height < 0) { + height = -height; + src_ar30 = src_ar30 + (height - 1) * src_stride_ar30; + src_stride_ar30 = -src_stride_ar30; + } + // Coalesce rows. + if (src_stride_ar30 == width * 4 && dst_stride_abgr == width * 4) { + width *= height; + height = 1; + src_stride_ar30 = dst_stride_abgr = 0; + } + for (y = 0; y < height; ++y) { + AR30ToABGRRow_C(src_ar30, dst_abgr, width); + src_ar30 += src_stride_ar30; + dst_abgr += dst_stride_abgr; + } + return 0; +} + // Convert NV12 to ARGB with matrix static int NV12ToARGBMatrix(const uint8_t* src_y, int src_stride_y, diff --git a/source/row_common.cc b/source/row_common.cc index 737d55979..a34dda407 100644 --- a/source/row_common.cc +++ b/source/row_common.cc @@ -195,6 +195,23 @@ void AR30ToARGBRow_C(const uint8_t* src_ar30, uint8_t* dst_argb, int width) { } } +void AR30ToABGRRow_C(const uint8_t* src_ar30, uint8_t* dst_abgr, int width) { + int x; + for (x = 0; x < width; ++x) { + uint32_t ar30 = *(uint32_t*)src_ar30; + uint32_t b = ar30 & 0x3ff; + uint32_t g = (ar30 >> 10) & 0x3ff; + uint32_t r = (ar30 >> 20) & 0x3ff; + uint32_t a = (ar30 >> 30) & 0x3; + dst_abgr[0] = r >> 2; + dst_abgr[1] = g >> 2; + dst_abgr[2] = b >> 2; + dst_abgr[3] = a * 0x55; + dst_abgr += 4; + src_ar30 += 4; + } +} + void ARGBToRGB24Row_C(const uint8_t* src_argb, uint8_t* dst_rgb, int width) { int x; for (x = 0; x < width; ++x) { diff --git a/unit_test/convert_test.cc b/unit_test/convert_test.cc index c3d8d229d..f4382882c 100644 --- a/unit_test/convert_test.cc +++ b/unit_test/convert_test.cc @@ -1081,6 +1081,7 @@ TESTATOB(RGB565, 2, 2, 1, ARGB, 4, 4, 1, 0) TESTATOB(ARGB1555, 2, 2, 1, ARGB, 4, 4, 1, 0) TESTATOB(ARGB4444, 2, 2, 1, ARGB, 4, 4, 1, 0) TESTATOB(AR30, 4, 4, 1, ARGB, 4, 4, 1, 0) +TESTATOB(AR30, 4, 4, 1, ABGR, 4, 4, 1, 0) TESTATOB(YUY2, 2, 4, 1, ARGB, 4, 4, 1, ARM_YUV_ERROR) TESTATOB(UYVY, 2, 4, 1, ARGB, 4, 4, 1, ARM_YUV_ERROR) TESTATOB(YUY2, 2, 4, 1, Y, 1, 1, 1, 0) @@ -1944,6 +1945,7 @@ TESTQPLANARTOE(I420Alpha, 2, 2, ABGR, 1, 4, ARGB, 4) // Caveat: Destination needs to be 4 bytes TESTPLANETOE(ARGB, 1, 4, AR30, 1, 4, ARGB, 4) +TESTPLANETOE(AR30, 1, 4, ARGB, 1, 4, ABGR, 4) // TESTPLANETOE(ARGB, 1, 4, AR30, 1, 4, ABGR, 4)