diff --git a/frameworks/innerkitsimpl/codec/src/image_source.cpp b/frameworks/innerkitsimpl/codec/src/image_source.cpp index efa8294c5306580a1bbc35495d78a2af9802fdb0..151a1357d581060cd94ef270f65eef7aeeb84a73 100644 --- a/frameworks/innerkitsimpl/codec/src/image_source.cpp +++ b/frameworks/innerkitsimpl/codec/src/image_source.cpp @@ -4181,6 +4181,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 c88743eca1460e2d1b9e68829fcd7760a0a00899..5200d72a5c5a676228397bd123d4554e72e62a68 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 @@ -56,6 +56,12 @@ static const std::string IMAGE_INPUT_JPEG_BROKEN_TWO = "/data/local/tmp/image/te 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_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; @@ -3171,5 +3177,133 @@ HWTEST_F(ImageSourceTest, WideGamutTest002, TestSize.Level3) Media::PixelFormat pixelFormat = pixelMap->GetPixelFormat(); ASSERT_EQ(pixelFormat, Media::PixelFormat::RGBA_1010102); } + +/** + * @tc.name: LargeImageTest001 + * @tc.desc: test decode supported large image(JPEG), using default decode options, expect decode 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 decode supported large image(JPEG), using valid desiredSize decode options, expect decode 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 decode unsupported large image(GIF), using valid desiredSize decode options, expect decode 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 decode supported large image(JPEG), + * using valid desiredSize and valid desiredRegion(scale first) decode options, + * expect decode success, output pixelmap size is equal to desiredRegion size. + * process: + * 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 decode supported large image(JPEG), + * using valid desiredSize and valid desiredRegion(crop first) decode options, + * expect decode success, output pixelmap size is equal to desiredSize size. + * process: + * 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..70c16cb0001ca43c6d96f2699d121c8d7c5af30d 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 @@ -190,8 +191,8 @@ private: static constexpr uint32_t ALIGN_16 = 16; #endif OHOS::Media::CropAndScaleStrategy cropAndScaleStrategy_ = OHOS::Media::CropAndScaleStrategy::DEFAULT; - OHOS::Media::Size RegiondesiredSize_; - bool SupportRegionFlag_; + OHOS::Media::Size regionDesiredSize_; + bool supportRegionFlag_; //Yuv OHOS::Media::Size desiredSizeYuv_; int softSampleSize_ = 1; diff --git a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp index 67cbbab4cc076a26ea939010c8f9c0a3a33ec0cd..c31f5d7841f63d6d6b26425bcd64a221ebd6f0d8 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; @@ -623,7 +621,7 @@ bool ExtDecoder::IsSupportCropOnDecode(SkIRect &target) { bool cond = info_.isEmpty() && !DecodeHeader(); CHECK_ERROR_RETURN_RET(cond, false); - if (SupportRegionFlag_) { + if (supportRegionFlag_) { return true; } SkIRect orgbounds = info_.bounds(); @@ -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); @@ -773,8 +786,8 @@ uint32_t ExtDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions & info.pixelFormat = opts.desiredPixelFormat; } } - RegiondesiredSize_.width = opts.desiredSize.width; - RegiondesiredSize_.height = opts.desiredSize.height; + regionDesiredSize_.width = opts.desiredSize.width; + regionDesiredSize_.height = opts.desiredSize.height; // SK only support low down scale int dstWidth = opts.desiredSize.width; int dstHeight = opts.desiredSize.height; @@ -804,9 +817,9 @@ 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); + supportRegionFlag_ = IsRegionDecodeSupported(index, opts, info); #ifdef SK_ENABLE_OHOS_CODEC if (IsSupportSampleDecode(opts.desiredPixelFormat) && GetSampleSize(opts.desiredSize.width, opts.desiredSize.height)) { @@ -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; @@ -1056,6 +1071,9 @@ uint32_t ExtDecoder::DoHeifSharedMemDecode(DecodeContext &context) rowStride = static_cast(dstInfo_.width()); byteCount = JpegDecoderYuv::GetYuvOutSize(dstInfo_.width(), dstInfo_.height()); } + 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)); CHECK_ERROR_RETURN_RET(!SetOutPutFormat(context.info.pixelFormat, decoder), ERR_IMAGE_DATA_UNSUPPORT); uint32_t res = ShareMemAlloc(context, byteCount); CHECK_ERROR_RETURN_RET(res != SUCCESS, res); @@ -1072,38 +1090,38 @@ 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_)); + 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"); - int sampleSize = GetSoftwareScaledSize(RegiondesiredSize_.width, RegiondesiredSize_.height); + bool cond = skOHOSCodec == nullptr || !skOHOSCodec->getSupportedSubset(&decodeSubset); + 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); - SkISize scaledSize = SkOHOSCodec->getSampledSubsetDimensions(sampleSize, decodeSubset); + SkISize scaledSize = skOHOSCodec->getSampledSubsetDimensions(sampleSize, decodeSubset); 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); + res = 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()); } @@ -1111,20 +1129,20 @@ SkCodec::Result ExtDecoder::DoRegionDecode(DecodeContext &context) SkOHOSCodec::OHOSOptions options; options.fSampleSize = sampleSize; options.fSubset = &decodeSubset; - SkCodec::Result result = SkOHOSCodec->getOHOSPixels(decodeInfo, dstBuffer, rowStride, &options); + SkCodec::Result result = skOHOSCodec->getOHOSPixels(decodeInfo, dstBuffer, rowStride, &options); switch (result) { case SkCodec::kSuccess: case SkCodec::kIncompleteInput: 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 } @@ -1257,6 +1275,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)) { @@ -1333,16 +1354,12 @@ uint32_t ExtDecoder::DoHeifDecode(DecodeContext &context) uint32_t ExtDecoder::Decode(uint32_t index, DecodeContext &context) { #ifdef SK_ENABLE_OHOS_CODEC - if (SupportRegionFlag_) { + 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_); @@ -2506,6 +2523,7 @@ uint32_t ExtDecoder::GetTopLevelImageNum(uint32_t &num) } bool ExtDecoder::IsSupportHardwareDecode() { +#ifdef JPEG_HW_DECODE_ENABLE if (info_.isEmpty() && !DecodeHeader()) { return false; } @@ -2513,10 +2531,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; @@ -2527,6 +2548,7 @@ bool ExtDecoder::IsSupportHardwareDecode() { return true; } } +#endif return false; } @@ -2589,6 +2611,10 @@ 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()); + uint64_t dstByteCount = static_cast(dstInfo_.computeMinByteSize()); + CHECK_ERROR_RETURN_RET_LOG(SkImageInfo::ByteSizeOverflowed(dstByteCount), ERR_IMAGE_TOO_LARGE, + "%{public}s not support sample decode, original image size: %{public}llu", __func__, + static_cast(dstByteCount)); 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 143454a61a790e256f33cf6a1bf5108630b2f901..8289eae36feb69c7b812cbc64b71e88c9d13e4d1 100644 --- a/test/resource/image/ohos_test.xml +++ b/test/resource/image/ohos_test.xml @@ -98,6 +98,7 @@