diff --git a/frameworks/innerkitsimpl/converter/src/pixel_convert.cpp b/frameworks/innerkitsimpl/converter/src/pixel_convert.cpp index 64e813c8198db554d74b8bb8c248a251e6382fea..922acf27064f50b41d511caf039a45ecf918637f 100644 --- a/frameworks/innerkitsimpl/converter/src/pixel_convert.cpp +++ b/frameworks/innerkitsimpl/converter/src/pixel_convert.cpp @@ -93,6 +93,7 @@ constexpr uint32_t BIT_SHIFT_16BITS = 16; constexpr uint32_t EVEN_ALIGNMENT = 2; constexpr int32_t CONVERT_ERROR = -1; constexpr uint32_t UV_PLANES_COUNT = 2; +constexpr uint8_t RGB565_EXTRA_BYTES = 2; static const std::map SWS_CS_COEFFICIENT = { {YuvConversion::BT601, SWS_CS_DEFAULT}, @@ -1338,6 +1339,31 @@ static bool P010ConvertRGBA1010102(const void *srcPixels, ImageInfo srcInfo, return true; } +static bool P010ConvertRGB565(const uint8_t* srcP010, const ImageInfo& srcInfo, + void* dstPixels, const ImageInfo& dstInfo) +{ + int64_t bufferSize = GetValidBufferSize(dstInfo); + if (bufferSize <= 0) { + return false; + } + + std::unique_ptr tmpBuffer = + std::make_unique(bufferSize + RGB565_EXTRA_BYTES); // avoid ffmpeg out-bounds-write + if (tmpBuffer == nullptr) { + IMAGE_LOGE("P010ConvertRGB565: alloc temp buffer failed"); + return false; + } + if (!ConvertForFFMPEG(srcP010, srcInfo.pixelFormat, srcInfo, tmpBuffer.get(), dstInfo.pixelFormat)) { + IMAGE_LOGE("P010ConvertRGB565: FFMpeg convert failed"); + return false; + } + if (memcpy_s(dstPixels, bufferSize, tmpBuffer.get(), bufferSize) != 0) { + IMAGE_LOGE("P010ConvertRGB565: memcpy_s dstPixels failed!"); + return false; + } + return true; +} + static bool ConvertRGBA1010102ToYUV(const void *srcPixels, ImageInfo srcInfo, void *dstPixels, ImageInfo dstInfo) { @@ -1485,6 +1511,11 @@ static int32_t ConvertFromP010(const void *srcPixels, const int32_t srcLength, c return PixelMap::GetRGBxByteCount(dstInfo); } return -1; + } else if (dstInfo.pixelFormat == PixelFormat::RGB_565) { + if (P010ConvertRGB565(srcP010, srcInfo, dstPixels, dstInfo)) { + return PixelMap::GetRGBxByteCount(dstInfo); + } + return -1; } else { if (ConvertForFFMPEG(srcP010, srcInfo.pixelFormat, srcInfo, dstPixels, dstInfo.pixelFormat)) { return PixelMap::GetRGBxByteCount(dstInfo); diff --git a/frameworks/innerkitsimpl/test/unittest/image_format_convert_test.cpp b/frameworks/innerkitsimpl/test/unittest/image_format_convert_test.cpp index 6de636f3b50271d4a8cb751ab438a8d1d3c1cd6f..affe02cfa957a33eed13e1aaa9e6c980f5ccef9d 100644 --- a/frameworks/innerkitsimpl/test/unittest/image_format_convert_test.cpp +++ b/frameworks/innerkitsimpl/test/unittest/image_format_convert_test.cpp @@ -2214,6 +2214,28 @@ HWTEST_F(ImageFormatConvertTest, PixelMapFormatConvert_032, TestSize.Level3) GTEST_LOG_(INFO) << "ImageFormatConvertTest.PixelMapFormatConvert_032: end"; } +HWTEST_F(ImageFormatConvertTest, PixelMapFormatConvert_033, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageFormatConvertTest: PixelMapFormatConvert_033: start"; + PixelFormat srcFormat = PixelFormat::YCRCB_P010; + PixelFormat destFormat = PixelFormat::RGB_565; + Size srcSize = { ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT }; + uint32_t destBuffersize = srcSize.width * srcSize.height * BYTES_PER_PIXEL_RGB565; + PixelMap10bitConvert(srcFormat, destFormat, srcSize, destBuffersize); + GTEST_LOG_(INFO) << "ImageFormatConvertTest: PixelMapFormatConvert_033: end"; +} + +HWTEST_F(ImageFormatConvertTest, PixelMapFormatConvert_034, TestSize.Level3) +{ + GTEST_LOG_(INFO) << "ImageFormatConvertTest.PixelMapFormatConvert_034: start"; + PixelFormat srcFormat = PixelFormat::YCBCR_P010; + PixelFormat destFormat = PixelFormat::RGB_565; + Size srcSize = { ODDTREE_ORIGINAL_WIDTH, ODDTREE_ORIGINAL_HEIGHT }; + uint32_t destBuffersize = srcSize.width * srcSize.height * BYTES_PER_PIXEL_RGB565; + PixelMap10bitConvert(srcFormat, destFormat, srcSize, destBuffersize); + GTEST_LOG_(INFO) << "ImageFormatConvertTest.PixelMapFormatConvert_034: end"; +} + /** * @tc.name: RGBConvertImageFormatOptionUnique_001 * @tc.desc: Verify RGB convert image format option using RGBConvertImageFormatOptionUnique.