From 12e5731a51a777533628dde3aa8caca929afc961 Mon Sep 17 00:00:00 2001 From: zhaona45 Date: Thu, 28 Aug 2025 11:26:13 +0800 Subject: [PATCH] Allow downsample decode large images. Signed-off-by: zhaona45 --- .../innerkitsimpl/codec/src/image_source.cpp | 2 + .../image_source_test/image_source_test.cpp | 128 ++++++++++++++++++ .../image/libextplugin/include/ext_decoder.h | 3 +- .../image/libextplugin/src/ext_decoder.cpp | 87 +++++++----- .../image/images/fake_large_size_test.jpg | Bin 0 -> 38973 bytes test/resource/image/ohos_test.xml | 1 + 6 files changed, 189 insertions(+), 32 deletions(-) create mode 100644 test/resource/image/images/fake_large_size_test.jpg diff --git a/frameworks/innerkitsimpl/codec/src/image_source.cpp b/frameworks/innerkitsimpl/codec/src/image_source.cpp index 1f8e7ab71..f6d743256 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 7dbdb8c90..68a6f871e 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 ae0e6d27b..e27ccb693 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 de64961b5..525a8857a 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 GIT binary patch literal 38973 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