diff --git a/frameworks/innerkitsimpl/codec/src/image_source.cpp b/frameworks/innerkitsimpl/codec/src/image_source.cpp index 1f8e7ab719c122b41b7a4fafff26bf0731080f8f..f6d7432567ebd43d766ca421816a18d3f0c73e95 100644 --- a/frameworks/innerkitsimpl/codec/src/image_source.cpp +++ b/frameworks/innerkitsimpl/codec/src/image_source.cpp @@ -4182,6 +4182,8 @@ DecodeContext ImageSource::DecodeImageDataToContext(uint32_t index, ImageInfo in FreeContextBuffer(context.freeFunc, context.allocatorType, context.pixelsBuffer); return context; } + IMAGE_LOGD("Decode success, context out size: (%{public}d, %{public}d), scale: %{public}f", + plInfo.size.width, plInfo.size.height, (static_cast(plInfo.size.width) / info.size.width)); if (IsSingleHdrImage(decodedHdrType)) { return HandleSingleHdrImage(decodedHdrType, context, plInfo); } diff --git a/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_test.cpp b/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_test.cpp index 7dbdb8c908bc3399b8572f156516d7935a59e5c2..68a6f871e95d9a6e80f2e5de54f4d7834a9f7093 100644 --- a/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_test.cpp +++ b/frameworks/innerkitsimpl/test/unittest/image_source_test/image_source_test.cpp @@ -57,6 +57,12 @@ static const std::string IMAGE_URL_PREFIX = "data:image/"; static const std::string IMAGE_INPUT_JPG_PATH_EXACTSIZE = "/data/local/tmp/image/800-500.jpg"; static const std::string IMAGE_JPG_THREE_GAINMAP_HDR_PATH = "/data/local/tmp/image/three_gainmap_hdr.jpg"; static const std::string IMAGE_HEIC_THREE_GAINMAP_HDR_PATH = "/data/local/tmp/image/three_gainmap_hdr.heic"; +static const std::string IMAGE_GIF_LARGE_SIZE_PATH = "/data/local/tmp/image/fake_large_size_test.gif"; // 50000x50000 +static const std::string IMAGE_JPG_LARGE_SIZE_PATH = "/data/local/tmp/image/fake_large_size_test.jpg"; // 30000x30000 +static const int32_t DECODE_DESIRED_WIDTH = 7500; +static const int32_t DECODE_DESIRED_HEIGHT = 7500; +static const int32_t DESIRED_REGION_WIDTH = 4096; +static const int32_t DESIRED_REGION_HEIGHT = 4096; static const int32_t DEFAULT_DMA_SIZE = 512 * 512; static const int32_t NUM_1_MINUS = -1; static const int32_t IMAGE_INPUT_JPG_WIDTH = 800; @@ -3198,5 +3204,127 @@ HWTEST_F(ImageSourceTest, WideGamutTest003, TestSize.Level3) Media::PixelFormat pixelFormat = pixelMap->GetPixelFormat(); ASSERT_EQ(pixelFormat, Media::PixelFormat::RGBA_1010102); } + +/** + * @tc.name: LargeImageTest001 + * @tc.desc: test decode large image(JPEG) fail + * @tc.type: FUNC + */ +HWTEST_F(ImageSourceTest, LargeImageTest001, TestSize.Level3) +{ + uint32_t errorCode = 0; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(IMAGE_JPG_LARGE_SIZE_PATH, + opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(imageSource, nullptr); + + uint32_t index = 0; + DecodeOptions decodeOpts; + std::unique_ptr pixelMap = imageSource->CreatePixelMap(index, decodeOpts, errorCode); + ASSERT_EQ(errorCode, ERR_IMAGE_TOO_LARGE); +} + +/** + * @tc.name: LargeImageTest002 + * @tc.desc: test down sample decode large image(JPEG) success + * @tc.type: FUNC + */ +HWTEST_F(ImageSourceTest, LargeImageTest002, TestSize.Level3) +{ + uint32_t errorCode = 0; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(IMAGE_JPG_LARGE_SIZE_PATH, + opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(imageSource, nullptr); + + uint32_t index = 0; + DecodeOptions decodeOpts; + decodeOpts.desiredSize = {DECODE_DESIRED_WIDTH, DECODE_DESIRED_HEIGHT}; + std::unique_ptr pixelMap = imageSource->CreatePixelMap(index, decodeOpts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(pixelMap, nullptr); + + ASSERT_EQ(pixelMap->GetWidth(), DECODE_DESIRED_WIDTH); + ASSERT_EQ(pixelMap->GetHeight(), DECODE_DESIRED_HEIGHT); +} + +/** + * @tc.name: LargeImageTest003 + * @tc.desc: test down sample decode large image(GIF) fail + * @tc.type: FUNC + */ +HWTEST_F(ImageSourceTest, LargeImageTest003, TestSize.Level3) +{ + uint32_t errorCode = 0; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(IMAGE_GIF_LARGE_SIZE_PATH, + opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(imageSource, nullptr); + + uint32_t index = 0; + DecodeOptions decodeOpts; + decodeOpts.desiredSize = {DECODE_DESIRED_WIDTH, DECODE_DESIRED_HEIGHT}; + std::unique_ptr pixelMap = imageSource->CreatePixelMap(index, decodeOpts, errorCode); + ASSERT_EQ(errorCode, ERR_IMAGE_TOO_LARGE); +} + +/** + * @tc.name: LargeImageTest004 + * @tc.desc: test down sample decode large image(JPEG) success with desiredRegion(scale first) + * src size(30000x30000) -> sample decode size(7500x7500) -> crop size(4096x4096) + * @tc.type: FUNC + */ +HWTEST_F(ImageSourceTest, LargeImageTest004, TestSize.Level3) +{ + uint32_t errorCode = 0; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(IMAGE_JPG_LARGE_SIZE_PATH, + opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(imageSource, nullptr); + + uint32_t index = 0; + DecodeOptions decodeOpts; + decodeOpts.desiredSize = {DECODE_DESIRED_WIDTH, DECODE_DESIRED_HEIGHT}; + decodeOpts.CropRect = {0, 0, DESIRED_REGION_WIDTH, DESIRED_REGION_HEIGHT}; + decodeOpts.cropAndScaleStrategy = CropAndScaleStrategy::SCALE_FIRST; + std::unique_ptr pixelMap = imageSource->CreatePixelMap(index, decodeOpts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(pixelMap, nullptr); + + ASSERT_EQ(pixelMap->GetWidth(), DESIRED_REGION_WIDTH); + ASSERT_EQ(pixelMap->GetHeight(), DESIRED_REGION_HEIGHT); +} + +/** + * @tc.name: LargeImageTest005 + * @tc.desc: test down sample decode large image(JPEG) success with desiredRegion(crop first) + * src size(30000x30000) -> region decode size(4096x4096) -> scale size(7500x7500) + * @tc.type: FUNC + */ +HWTEST_F(ImageSourceTest, LargeImageTest005, TestSize.Level3) +{ + uint32_t errorCode = 0; + SourceOptions opts; + std::unique_ptr imageSource = ImageSource::CreateImageSource(IMAGE_JPG_LARGE_SIZE_PATH, + opts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(imageSource, nullptr); + + uint32_t index = 0; + DecodeOptions decodeOpts; + decodeOpts.desiredSize = {DECODE_DESIRED_WIDTH, DECODE_DESIRED_HEIGHT}; + decodeOpts.CropRect = {0, 0, DESIRED_REGION_WIDTH, DESIRED_REGION_HEIGHT}; + decodeOpts.cropAndScaleStrategy = CropAndScaleStrategy::CROP_FIRST; + std::unique_ptr pixelMap = imageSource->CreatePixelMap(index, decodeOpts, errorCode); + ASSERT_EQ(errorCode, SUCCESS); + ASSERT_NE(pixelMap, nullptr); + + ASSERT_EQ(pixelMap->GetWidth(), DECODE_DESIRED_WIDTH); + ASSERT_EQ(pixelMap->GetHeight(), DECODE_DESIRED_HEIGHT); +} } // namespace Multimedia } // namespace OHOS \ No newline at end of file diff --git a/plugins/common/libs/image/libextplugin/include/ext_decoder.h b/plugins/common/libs/image/libextplugin/include/ext_decoder.h index ae0e6d27bb4c008622117f50214cb92ac7d60bfc..e27ccb6932969ec57c8b62c306c32751991027a4 100644 --- a/plugins/common/libs/image/libextplugin/include/ext_decoder.h +++ b/plugins/common/libs/image/libextplugin/include/ext_decoder.h @@ -122,6 +122,7 @@ private: uint32_t SetContextPixelsBuffer(uint64_t byteCount, DecodeContext &context); uint32_t GetMakerImagePropertyString(const std::string &key, std::string &value); uint32_t CheckDecodeOptions(uint32_t index, const PixelDecodeOptions &opts); + uint32_t CheckCropRect(const PixelDecodeOptions &opts); static void ReportImageType(SkEncodedImageFormat skEncodeFormat); bool CheckContext(const DecodeContext &context); uint32_t DmaMemAlloc(DecodeContext &context, uint64_t count, SkImageInfo &dstInfo); @@ -147,7 +148,7 @@ private: bool FrameCacheInfoIsEqual(FrameCacheInfo& src, FrameCacheInfo& dst); uint32_t UpdateHardWareDecodeInfo(DecodeContext &context); bool IsRegionDecodeSupported(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info); - SkCodec::Result DoRegionDecode(DecodeContext &context); + uint32_t DoRegionDecode(DecodeContext &context); SkCodec::Result DoSampleDecode(DecodeContext &context); bool IsRawFormat(std::string &name); std::string GetPluginType() override diff --git a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp index de64961b55da337cee1528e4f8dc6237537b6467..525a8857a3e72875e4b2766ef8b8429252736918 100644 --- a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp +++ b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp @@ -101,9 +101,7 @@ namespace { constexpr static uint32_t DESC_SIGNATURE = 0x64657363; constexpr static size_t SIZE_1 = 1; constexpr static size_t SIZE_4 = 4; - constexpr static int HARDWARE_MIN_DIM = 512; constexpr static int HARDWARE_MID_DIM = 1024; - constexpr static int HARDWARE_MAX_DIM = 8192; constexpr static int HARDWARE_ALIGN_SIZE = 16; constexpr static int DEFAULT_SCALE_SIZE = 1; constexpr static int DOUBLE_SCALE_SIZE = 2; @@ -704,23 +702,25 @@ static sk_sp getDesiredColorSpace(SkImageInfo &srcInfo, const Pixe return opts.plDesiredColorSpace->ToSkColorSpace(); } +static bool IsSampleDecodeFormat(SkEncodedImageFormat format) +{ + return format == SkEncodedImageFormat::kJPEG || format == SkEncodedImageFormat::kHEIF || + format == SkEncodedImageFormat::kPNG; +} + uint32_t ExtDecoder::CheckDecodeOptions(uint32_t index, const PixelDecodeOptions &opts) { bool cond = ImageUtils::CheckMulOverflow(dstInfo_.width(), dstInfo_.height(), dstInfo_.bytesPerPixel()); CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, "SetDecodeOptions failed, width:%{public}d, height:%{public}d is too large", dstInfo_.width(), dstInfo_.height()); - IMAGE_LOGD("%{public}s IN, opts.CropRect: xy [%{public}d x %{public}d] wh [%{public}d x %{public}d]", - __func__, opts.CropRect.left, opts.CropRect.top, opts.CropRect.width, opts.CropRect.height); - cond = !IsValidCrop(opts.CropRect, info_, dstSubset_); - CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, - "Invalid crop rect top:%{public}d, bottom:%{public}d, left:%{public}d, right:%{public}d", - dstSubset_.top(), dstSubset_.bottom(), dstSubset_.left(), dstSubset_.right()); - IMAGE_LOGI("%{public}s IN, dstSubset_: xy [%{public}d x %{public}d] right,bottom: [%{public}d x %{public}d]", - __func__, dstSubset_.left(), dstSubset_.top(), dstSubset_.right(), dstSubset_.bottom()); size_t tempSrcByteCount = info_.computeMinByteSize(); size_t tempDstByteCount = dstInfo_.computeMinByteSize(); - cond = SkImageInfo::ByteSizeOverflowed(tempSrcByteCount) || SkImageInfo::ByteSizeOverflowed(tempDstByteCount); + bool srcOverflowed = SkImageInfo::ByteSizeOverflowed(tempSrcByteCount); + bool dstOverflowed = SupportRegionFlag_ ? false : SkImageInfo::ByteSizeOverflowed(tempDstByteCount); + IMAGE_LOGD("%{public}s srcOverflowed: %{public}d, dstOverflowed: %{public}d, SupportRegionFlag_: %{public}d", + __func__, srcOverflowed, dstOverflowed, SupportRegionFlag_); + cond = IsSampleDecodeFormat(codec_->getEncodedFormat()) ? dstOverflowed : (srcOverflowed || dstOverflowed); CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_TOO_LARGE, "Image too large, srcInfo_height: %{public}d, srcInfo_width: %{public}d, " "dstInfo_height: %{public}d, dstInfo_width: %{public}d", @@ -733,6 +733,19 @@ uint32_t ExtDecoder::CheckDecodeOptions(uint32_t index, const PixelDecodeOptions return SUCCESS; } +uint32_t ExtDecoder::CheckCropRect(const PixelDecodeOptions &opts) +{ + IMAGE_LOGD("%{public}s IN, opts.CropRect: xy [%{public}d x %{public}d] wh [%{public}d x %{public}d]", + __func__, opts.CropRect.left, opts.CropRect.top, opts.CropRect.width, opts.CropRect.height); + bool cond = !IsValidCrop(opts.CropRect, info_, dstSubset_); + CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_INVALID_PARAMETER, + "Invalid crop rect top:%{public}d, bottom:%{public}d, left:%{public}d, right:%{public}d", + dstSubset_.top(), dstSubset_.bottom(), dstSubset_.left(), dstSubset_.right()); + IMAGE_LOGD("%{public}s IN, dstSubset_: xy [%{public}d x %{public}d] right,bottom: [%{public}d x %{public}d]", + __func__, dstSubset_.left(), dstSubset_.top(), dstSubset_.right(), dstSubset_.bottom()); + return SUCCESS; +} + bool ExtDecoder::IsRegionDecodeSupported(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info) { CHECK_ERROR_RETURN_RET(PreDecodeCheck(index) != SUCCESS, false); @@ -804,7 +817,7 @@ uint32_t ExtDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions & } else { SetHeifSampleSize(opts, dstWidth, dstHeight, desireColor, desireAlpha); } - auto resCode = CheckDecodeOptions(index, opts); + uint32_t resCode = CheckCropRect(opts); CHECK_ERROR_RETURN_RET(resCode != SUCCESS, resCode); SupportRegionFlag_ = IsRegionDecodeSupported(index, opts, info); #ifdef SK_ENABLE_OHOS_CODEC @@ -816,6 +829,8 @@ uint32_t ExtDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions & getDesiredColorSpace(info_, opts)); } #endif + resCode = CheckDecodeOptions(index, opts); + CHECK_ERROR_RETURN_RET(resCode != SUCCESS, resCode); info.size.width = dstInfo_.width(); info.size.height = dstInfo_.height(); reusePixelmap_ = opts.plReusePixelmap; @@ -1046,6 +1061,9 @@ uint32_t ExtDecoder::DoHeifSharedMemDecode(DecodeContext &context) CHECK_ERROR_RETURN_RET_LOG(decoder == nullptr, ERR_IMAGE_DATA_UNSUPPORT, "Decode HeifDecoder is nullptr"); uint64_t rowStride = dstInfo_.minRowBytes64(); uint64_t byteCount = dstInfo_.computeMinByteSize(); + CHECK_ERROR_RETURN_RET_LOG(SkImageInfo::ByteSizeOverflowed(byteCount), ERR_IMAGE_TOO_LARGE, + "%{public}s not support sample decode, original image size: %{public}llu", __func__, + static_cast(byteCount)); if (IsYuv420Format(context.info.pixelFormat)) { rowStride = static_cast(dstInfo_.width()); byteCount = JpegDecoderYuv::GetYuvOutSize(dstInfo_.width(), dstInfo_.height()); @@ -1066,14 +1084,14 @@ uint32_t ExtDecoder::DoHeifSharedMemDecode(DecodeContext &context) #endif } -SkCodec::Result ExtDecoder::DoRegionDecode(DecodeContext &context) +uint32_t ExtDecoder::DoRegionDecode(DecodeContext &context) { #ifdef SK_ENABLE_OHOS_CODEC auto SkOHOSCodec = SkOHOSCodec::MakeFromCodec(std::move(codec_)); // Ask the codec for a scaled subset SkIRect decodeSubset = dstSubset_; bool cond = SkOHOSCodec == nullptr || !SkOHOSCodec->getSupportedSubset(&decodeSubset); - CHECK_ERROR_RETURN_RET_LOG(cond, SkCodec::kErrorInInput, "Error: Could not get subset"); + CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DECODE_FAILED, "Error: Could not get subset"); int sampleSize = GetSoftwareScaledSize(RegiondesiredSize_.width, RegiondesiredSize_.height); ImageFuncTimer imageFuncTimer("%s, decodeSubset: left:%d, top:%d, width:%d, height:%d, sampleSize:%d", __func__, decodeSubset.left(), decodeSubset.top(), decodeSubset.width(), decodeSubset.height(), sampleSize); @@ -1081,23 +1099,23 @@ SkCodec::Result ExtDecoder::DoRegionDecode(DecodeContext &context) SkImageInfo decodeInfo = dstInfo_.makeWH(scaledSize.width(), scaledSize.height()); uint64_t byteCount = decodeInfo.computeMinByteSize(); + CHECK_ERROR_RETURN_RET_LOG(SkImageInfo::ByteSizeOverflowed(byteCount), ERR_IMAGE_TOO_LARGE, + "%{public}s too large region size: %{public}llu", __func__, static_cast(byteCount)); uint32_t res = 0; if (context.allocatorType == Media::AllocatorType::DMA_ALLOC) { res = DmaMemAlloc(context, byteCount, decodeInfo); } else if (context.allocatorType == Media::AllocatorType::SHARE_MEM_ALLOC) { ShareMemAlloc(context, byteCount); } - CHECK_ERROR_RETURN_RET_LOG(res != SUCCESS, SkCodec::kErrorInInput, + CHECK_ERROR_RETURN_RET_LOG(res != SUCCESS, ERR_IMAGE_DECODE_FAILED, "do region decode failed, SetContextPixelsBuffer failed"); uint8_t* dstBuffer = static_cast(context.pixelsBuffer.buffer); uint64_t rowStride = decodeInfo.minRowBytes64(); if (context.allocatorType == Media::AllocatorType::DMA_ALLOC) { SurfaceBuffer* sbBuffer = reinterpret_cast (context.pixelsBuffer.context); - if (sbBuffer == nullptr) { - IMAGE_LOGE("%{public}s: surface buffer is nullptr", __func__); - return SkCodec::kErrorInInput; - } + CHECK_ERROR_RETURN_RET_LOG(sbBuffer == nullptr, ERR_IMAGE_DECODE_FAILED, + "%{public}s: surface buffer is nullptr", __func__); rowStride = static_cast(sbBuffer->GetStride()); } @@ -1112,13 +1130,13 @@ SkCodec::Result ExtDecoder::DoRegionDecode(DecodeContext &context) case SkCodec::kErrorInInput: context.outInfo.size.width = decodeInfo.width(); context.outInfo.size.height = decodeInfo.height(); - return SkCodec::kSuccess; + return SUCCESS; default: IMAGE_LOGE("Error: Could not get pixels with message %{public}s", SkCodec::ResultToString(result)); - return result; + return ERR_IMAGE_DECODE_FAILED; } #else - return SkCodec::kSuccess; + return SUCCESS; #endif } @@ -1251,6 +1269,9 @@ bool ExtDecoder::DoHeifSwDecode(DecodeContext &context) } ReleaseOutputBuffer(context, context.allocatorType); uint64_t byteCount = info_.computeMinByteSize(); + CHECK_ERROR_RETURN_RET_LOG(SkImageInfo::ByteSizeOverflowed(byteCount), false, + "%{public}s not support sample decode, original image size: %{public}llu", __func__, + static_cast(byteCount)); //If the HWdecode failed, software does not support samplesize, allocate memory based on original image. bool cond = false; if (IsHeifToYuvDecode(context)) { @@ -1329,14 +1350,10 @@ uint32_t ExtDecoder::Decode(uint32_t index, DecodeContext &context) #ifdef SK_ENABLE_OHOS_CODEC if (SupportRegionFlag_) { DebugInfo(info_, dstInfo_, dstOptions_); - SkCodec::Result regionDecodeRes = DoRegionDecode(context); + uint32_t regionDecodeRes = DoRegionDecode(context); ResetCodec(); - if (SkCodec::kSuccess == regionDecodeRes) { - return SUCCESS; - } else { - IMAGE_LOGE("do region decode failed"); - return ERR_IMAGE_DECODE_FAILED; - } + CHECK_ERROR_PRINT_LOG(regionDecodeRes != SUCCESS, "do region decode failed"); + return regionDecodeRes; } if (IsSupportSampleDecode(context.info.pixelFormat)) { DebugInfo(info_, dstInfo_, dstOptions_); @@ -2500,6 +2517,7 @@ uint32_t ExtDecoder::GetTopLevelImageNum(uint32_t &num) } bool ExtDecoder::IsSupportHardwareDecode() { +#ifdef JPEG_HW_DECODE_ENABLE if (info_.isEmpty() && !DecodeHeader()) { return false; } @@ -2507,10 +2525,13 @@ bool ExtDecoder::IsSupportHardwareDecode() { && codec_->getEncodedFormat() == SkEncodedImageFormat::kJPEG)) { return false; } + if (!initJpegErr_ && hwDecoderPtr_ == nullptr) { + InitJpegDecoder(); + } + CHECK_ERROR_RETURN_RET_LOG((initJpegErr_ || hwDecoderPtr_ == nullptr), false, "Jpeg hardware decoder error"); int width = info_.width(); int height = info_.height(); - if (width >= HARDWARE_MIN_DIM && width <= HARDWARE_MAX_DIM - && height >= HARDWARE_MIN_DIM && height <= HARDWARE_MAX_DIM) { + if (hwDecoderPtr_->IsHardwareDecodeSupported(IMAGE_JPEG_FORMAT, {width, height})) { if (width < HARDWARE_MID_DIM || height < HARDWARE_MID_DIM) { int remWidth = width % HARDWARE_ALIGN_SIZE; int remHeight = height % HARDWARE_ALIGN_SIZE; @@ -2521,6 +2542,7 @@ bool ExtDecoder::IsSupportHardwareDecode() { return true; } } +#endif return false; } @@ -2583,6 +2605,9 @@ uint32_t ExtDecoder::DoHeifToSingleHdrDecode(DecodeContext &context) CHECK_ERROR_RETURN_RET_LOG(cond, ERR_IMAGE_DATA_UNSUPPORT, "SingleHdrDecode, HeifDecoder is nullptr"); uint64_t byteCount = static_cast(info_.computeMinByteSize()); + CHECK_ERROR_RETURN_RET_LOG(SkImageInfo::ByteSizeOverflowed(byteCount), ERR_IMAGE_TOO_LARGE, + "%{public}s not support sample decode, original image size: %{public}llu", __func__, + static_cast(byteCount)); if (context.info.pixelFormat == PixelFormat::YCBCR_P010 || context.info.pixelFormat == PixelFormat::YCRCB_P010) { uint32_t allocRet = HeifYUVMemAlloc(context, dstInfo_); cond = allocRet != SUCCESS; diff --git a/test/resource/image/images/fake_large_size_test.jpg b/test/resource/image/images/fake_large_size_test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d781623e571c457c873cb0df02719f2e21dc94b5 Binary files /dev/null and b/test/resource/image/images/fake_large_size_test.jpg differ diff --git a/test/resource/image/ohos_test.xml b/test/resource/image/ohos_test.xml index afd187e12c4f0c38bd6e8a6f9c5b6eb7db919f03..c8c8b07b64b1ce2b4f30eba33f6a1f1d3d33ab73 100644 --- a/test/resource/image/ohos_test.xml +++ b/test/resource/image/ohos_test.xml @@ -100,6 +100,7 @@