diff --git a/frameworks/innerkitsimpl/converter/src/image_format_convert_utils.cpp b/frameworks/innerkitsimpl/converter/src/image_format_convert_utils.cpp index f129ade2f67158e4bd7863d31e95597c68d0ba96..fe3ab7f661e039d62f41bcac96ecd901e8f63244 100644 --- a/frameworks/innerkitsimpl/converter/src/image_format_convert_utils.cpp +++ b/frameworks/innerkitsimpl/converter/src/image_format_convert_utils.cpp @@ -53,6 +53,12 @@ namespace { #define LOG_TAG "ImageFormatConvert" namespace OHOS { namespace Media { +struct SrcDataInfo { + int32_t width; + int32_t height; + PixelFormat format; + const uint8_t* buffer; +}; static AVPixelFormat findPixelFormat(PixelFormat format) { auto formatSearch = PixelConvertAdapter::FFMPEG_PIXEL_FORMAT_MAP.find(format); @@ -1141,6 +1147,69 @@ static bool YuvToYuvParam(const YUVDataInfo &yDInfo, SrcConvertParam &srcParam, return true; } +static bool ProcessSrcParamCore(const SrcDataInfo& srcData, SrcConvertParam& srcParam, + std::unique_ptr& copySrcBuffer) +{ + if (srcData.width <= 0 || srcData.height <= 0) { + IMAGE_LOGE("Invalid src width(%{public}d) or height(%{public}d)", srcData.width, srcData.height); + return false; + } + srcParam.buffer = srcData.buffer; + int32_t copyWidth = srcData.width; + int32_t copyHeight = srcData.height; + + if (srcData.width % EVEN_ALIGNMENT != 0 || srcData.height % EVEN_ALIGNMENT != 0) { + if (!ImageUtils::GetAlignedNumber(copyWidth, EVEN_ALIGNMENT) || + !ImageUtils::GetAlignedNumber(copyHeight, EVEN_ALIGNMENT)) { + IMAGE_LOGE("Failed to get aligned width/height"); + return false; + } + + int32_t pixelBytes = ImageUtils::GetPixelBytes(srcData.format); + if (pixelBytes == 0) { + IMAGE_LOGE("Invalid pixel bytes(%{public}d) for format", pixelBytes); + return false; + } + int32_t srcDataLen = srcData.width * srcData.height * pixelBytes; + int32_t copySrcLen = copyWidth * copyHeight * pixelBytes; + + copySrcBuffer = std::make_unique(copySrcLen); + if (copySrcBuffer == nullptr || EOK != memcpy_s(copySrcBuffer.get(), copySrcLen, srcData.buffer, srcDataLen)) { + IMAGE_LOGE("alloc memory or memcpy_s failed!"); + return false; + } + srcParam.buffer = copySrcBuffer.get(); + } + srcParam.width = static_cast(copyWidth); + srcParam.height = static_cast(copyHeight); + srcParam.format = srcData.format; + return true; +} + +static bool ProcessSrcParam(const YUVDataInfo& yDInfo, PixelFormat srcFormat, const uint8_t* srcBuffer, + SrcConvertParam& srcParam, std::unique_ptr& copySrcBuffer) +{ + SrcDataInfo srcData = { + static_cast(yDInfo.yWidth), + static_cast(yDInfo.yHeight), + srcFormat, + srcBuffer + }; + return ProcessSrcParamCore(srcData, srcParam, copySrcBuffer); +} + +static bool ProcessSrcParam(const RGBDataInfo& rgbInfo, PixelFormat srcFormat, const uint8_t* srcBuffer, + SrcConvertParam& srcParam, std::unique_ptr& copySrcBuffer) +{ + SrcDataInfo srcData = { + rgbInfo.width, + rgbInfo.height, + srcFormat, + srcBuffer + }; + return ProcessSrcParamCore(srcData, srcParam, copySrcBuffer); +} + static bool YuvToYuv(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo, PixelFormat srcFormat, DestConvertInfo &destInfo, PixelFormat destFormat) { @@ -1148,9 +1217,12 @@ static bool YuvToYuv(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo, PixelF yDInfo.uvWidth == 0 || yDInfo.uvHeight == 0 || destInfo.bufferSize == 0) { return false; } - SrcConvertParam srcParam = {yDInfo.yWidth, yDInfo.yHeight}; - srcParam.format = srcFormat; - srcParam.buffer = srcBuffer; + SrcConvertParam srcParam; + std::unique_ptr copySrcBuffer; + if (!ProcessSrcParam(yDInfo, srcFormat, srcBuffer, srcParam, copySrcBuffer)) { + IMAGE_LOGE("Process src param failed for YuvToYuv"); + return false; + } DestConvertParam destParam = {destInfo.width, destInfo.height}; destParam.format = destFormat; @@ -1173,9 +1245,12 @@ static bool YuvToRGB(const uint8_t *srcBuffer, const YUVDataInfo &yDInfo, PixelF yDInfo.uvWidth == 0 || yDInfo.uvHeight == 0 || destInfo.bufferSize == 0) { return false; } - SrcConvertParam srcParam = {yDInfo.yWidth, yDInfo.yHeight}; - srcParam.format = srcFormat; - srcParam.buffer = srcBuffer; + SrcConvertParam srcParam; + std::unique_ptr copySrcBuffer; + if (!ProcessSrcParam(yDInfo, srcFormat, srcBuffer, srcParam, copySrcBuffer)) { + IMAGE_LOGE("Process src param failed for YuvToRGB"); + return false; + } DestConvertParam destParam = {destInfo.width, destInfo.height}; destParam.format = destFormat; @@ -1198,28 +1273,12 @@ static bool RGBToYuv(const uint8_t *srcBuffer, const RGBDataInfo &rgbInfo, Pixel destInfo.bufferSize == 0) { return false; } - int32_t copyWidth = rgbInfo.width; - int32_t copyHeight = rgbInfo.height; SrcConvertParam srcParam; - srcParam.buffer = srcBuffer; std::unique_ptr copySrcBuffer; - if (rgbInfo.width % EVEN_ALIGNMENT != 0 || rgbInfo.height % EVEN_ALIGNMENT != 0) { - if (!ImageUtils::GetAlignedNumber(copyWidth, EVEN_ALIGNMENT) || - !ImageUtils::GetAlignedNumber(copyHeight, EVEN_ALIGNMENT)) { - return false; - } - int32_t copySrcLen = copyWidth * copyHeight * ImageUtils::GetPixelBytes(srcFormat); - int32_t rgbInfoLen = rgbInfo.width * rgbInfo.height * ImageUtils::GetPixelBytes(srcFormat); - copySrcBuffer = std::make_unique(copySrcLen); - if (copySrcBuffer == nullptr || EOK != memcpy_s(copySrcBuffer.get(), rgbInfoLen, srcBuffer, rgbInfoLen)) { - IMAGE_LOGE("alloc memory or memcpy_s failed!"); - return false; - } - srcParam.buffer = copySrcBuffer.get(); + if (!ProcessSrcParam(rgbInfo, srcFormat, srcBuffer, srcParam, copySrcBuffer)) { + IMAGE_LOGE("Process src param failed for RGBToYuv"); + return false; } - srcParam.width = static_cast(copyWidth); - srcParam.height = static_cast(copyHeight); - srcParam.format = srcFormat; DestConvertParam destParam = {destInfo.width, destInfo.height}; destParam.format = destFormat; diff --git a/frameworks/innerkitsimpl/test/unittest/image_format_convert_fail_test.cpp b/frameworks/innerkitsimpl/test/unittest/image_format_convert_fail_test.cpp index c2cfc130f94367a7db8c37bee5b2108cd5b4f5b3..99516a5a7ef07f9c89e173391ab948152c7fd01a 100644 --- a/frameworks/innerkitsimpl/test/unittest/image_format_convert_fail_test.cpp +++ b/frameworks/innerkitsimpl/test/unittest/image_format_convert_fail_test.cpp @@ -345,5 +345,29 @@ HWTEST_F(ImageFormatConvertFailTest, RGB1010102ConvertToYUVP010, TestSize.Level1 ConvertFunction cvtFunc = ImageFormatConvert::GetConvertFuncByFormat(srcFormat, destFormat); EXPECT_EQ(cvtFunc(srcBuffer, rgbInfo, destInfo, colorspace), false); } + +/** + * @tc.name: RGBAF16ConvertToYUV + * @tc.desc: Test RGBAF16ConvertToYUV with invalid info. + * @tc.type: FUNC + */ +HWTEST_F(ImageFormatConvertFailTest, RGBAF16ConvertToYUV, TestSize.Level1) +{ + PixelFormat srcFormat = PixelFormat::RGBA_F16; + PixelFormat destFormat = PixelFormat::NV21; + uint8_t srcBuffer[LENGTH] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; + RGBDataInfo rgbInfo; + rgbInfo.width = -1; + rgbInfo.height = -1; + ColorSpace colorspace = ColorSpace::UNKNOWN; + DestConvertInfo destInfo; + destInfo.width = 1; + destInfo.height = 1; + destInfo.buffer = new uint8_t[8]; + destInfo.bufferSize = 16; + + ConvertFunction cvtFunc = ImageFormatConvert::GetConvertFuncByFormat(srcFormat, destFormat); + EXPECT_EQ(cvtFunc(srcBuffer, rgbInfo, destInfo, colorspace), false); +} } // namespace Media } // namespace OHOS \ No newline at end of file