From 1ae91dc310490c3ff731f8940d0a71a5e66af08e Mon Sep 17 00:00:00 2001 From: JillFred Date: Mon, 30 Jun 2025 11:16:31 +0800 Subject: [PATCH 1/2] add test code for heif decode interface Signed-off-by: JillFred --- codec/bundle.json | 1 + codec/test/demo/heif/BUILD.gn | 45 +- .../heif/include/codec_heif_decode_helper.h | 99 +++++ codec/test/demo/heif/include/command_parser.h | 40 ++ .../heif/src/codec_heif_decode_helper.cpp | 399 ++++++++++++++++++ codec/test/demo/heif/src/command_parser.cpp | 212 ++++++++-- codec/test/demo/heif/src/heif_decoder.cpp | 27 ++ codec/test/demo/heif/src/heif_encoder.cpp | 8 +- codec/test/fuzztest/image_fuzzer/BUILD.gn | 1 + .../imagedoheifdecode_fuzzer/BUILD.gn | 63 +++ .../imagedoheifdecode_fuzzer/corpus/init | 14 + .../imagedoheifdecode_fuzzer.cpp | 188 +++++++++ .../imagedoheifdecode_fuzzer.h | 22 + .../imagedoheifdecode_fuzzer/project.xml | 25 ++ codec/test/unittest/hdi_image/BUILD.gn | 33 ++ .../hdi_image/codec_hdi_heif_decode_test.cpp | 311 ++++++++++++++ 16 files changed, 1445 insertions(+), 43 deletions(-) create mode 100644 codec/test/demo/heif/include/codec_heif_decode_helper.h create mode 100644 codec/test/demo/heif/src/codec_heif_decode_helper.cpp create mode 100644 codec/test/demo/heif/src/heif_decoder.cpp create mode 100644 codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/BUILD.gn create mode 100644 codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/corpus/init create mode 100644 codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.cpp create mode 100644 codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.h create mode 100644 codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/project.xml create mode 100644 codec/test/unittest/hdi_image/codec_hdi_heif_decode_test.cpp diff --git a/codec/bundle.json b/codec/bundle.json index c41568437e..9e1dfcee9c 100644 --- a/codec/bundle.json +++ b/codec/bundle.json @@ -34,6 +34,7 @@ "hdf_core", "hitrace", "hilog", + "init", "ipc", "openmax" ], diff --git a/codec/test/demo/heif/BUILD.gn b/codec/test/demo/heif/BUILD.gn index 06d9c7df16..fe2a2b110d 100644 --- a/codec/test/demo/heif/BUILD.gn +++ b/codec/test/demo/heif/BUILD.gn @@ -50,6 +50,49 @@ ohos_executable("codec_heif_encode") { part_name = "drivers_peripheral_codec" } +ohos_executable("codec_heif_decode") { + include_dirs = [ "./include" ] + + sources = [ + "src/codec_heif_decode_helper.cpp", + "src/command_parser.cpp", + "src/heif_decoder.cpp", + ] + + if (is_standard_system) { + external_deps = [ + "c_utils:utils", + "drivers_interface_codec:libimage_proxy_2.1", + "drivers_interface_display:libdisplay_buffer_proxy_1.0", + "drivers_interface_display:libdisplay_buffer_proxy_1.2", + "drivers_interface_display:libdisplay_composer_proxy_1.0", + "drivers_interface_display:libdisplay_composer_proxy_1.1", + "drivers_interface_display:libdisplay_composer_proxy_1.2", + "drivers_interface_display:libdisplay_buffer_hdi_impl_v1_2", + "drivers_interface_display:libdisplay_composer_hdi_impl_1.2", + "drivers_interface_display:libdisplay_commontype_proxy_2.0", + "hdf_core:libhdf_host", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hdf_core:libhdi", + "hilog:libhilog", + "init:libbegetutil", + "ipc:ipc_single", + "graphic_surface:buffer_handle", + "graphic_surface:surface", + ] + } else { + external_deps = [ "hilog:libhilog" ] + } + install_enable = false + install_images = [ chipset_base_dir ] + subsystem_name = "hdf" + part_name = "drivers_peripheral_codec" +} + group("codec_hdi_heif_demo") { - deps = [ ":codec_heif_encode" ] + deps = [ + ":codec_heif_decode", + ":codec_heif_encode" + ] } diff --git a/codec/test/demo/heif/include/codec_heif_decode_helper.h b/codec/test/demo/heif/include/codec_heif_decode_helper.h new file mode 100644 index 0000000000..cd73d7981c --- /dev/null +++ b/codec/test/demo/heif/include/codec_heif_decode_helper.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_HDI_CODEC_IMAGE_V2_1_CODEC_HEIF_DECODE_HELPER +#define OHOS_HDI_CODEC_IMAGE_V2_1_CODEC_HEIF_DECODE_HELPER + +#include +#include "command_parser.h" +#include "v2_1/icodec_image.h" +#include "v1_2/display_composer_type.h" +#include "v1_2/display_buffer_type.h" +#include "v1_2/include/idisplay_buffer.h" +#include "v2_0/cm_color_space.h" + +template +std::vector Pod2Vec(const T& t) +{ + const uint8_t* begin = reinterpret_cast(&t); + const uint8_t* end = begin + sizeof(T); + return std::vector(begin, end); +} + +namespace OHOS::VDI::HEIF { +class HeifDecoderHelper { +public: + explicit HeifDecoderHelper(const CommandOpt& opt) : decodeOpt_(opt) {} + ~HeifDecoderHelper() = default; + void DoDecode(); +private: + bool IsHeifHardwareDecodeSupported(OHOS::sptr& hdiHeifDecoder); + bool GetOutputFormat(); + bool ReadInput(std::vector>& inputs); + bool AllocateOutputBuffer(OHOS::sptr& output); + void DumpOutput(OHOS::sptr& output); + void GetSampleSize(); + void GetMetaDataInfo(OHOS::HDI::Display::Graphic::Common::V2_0::CM_ColorSpaceInfo& colorSpaceInfo); + +private: + class InputParser { + public: + explicit InputParser(const std::string& inputPath) : source_(inputPath) {} + ~InputParser() = default; + bool ParseGridInfo(OHOS::HDI::Codec::Image::V2_1::GridInfo& gridInfo); + bool ReadInput(std::vector>& inputs); + private: + void FindXpsAndIFrameFile(); + static void SplitString(const std::string& src, char sep, std::vector& vec); + static std::string JoinPath(const std::string& base, const std::string& append); + static bool ReadFileToAshmem(const std::string& filePath, std::vector>& inputs); + static int ExtractIFrameNum(const std::string& filePath); + + static constexpr char MAIN_SEP = '_'; + static constexpr size_t MIN_MAIN_SEG_CNT = 2; + static constexpr size_t MAX_MAIN_SEG_CNT = 4; + static constexpr char SUB_SEP = 'x'; + static constexpr size_t SUB_SEG_CNT = 2; + static constexpr char NO_GRID_INDICATOR[] = "nogrid"; + static constexpr char XPS_INDICATOR[] = "_hevc_xps"; + static constexpr char I_FRAME_INDICATOR[] = "_hevc_I"; + enum MainSeg { + DISPLAY_SIZE = 0, + GRID_FLAG, + TILE_SIZE, + GRID_SIZE + }; + enum SubSeg { + HORIZONTAL = 0, + VERTICAL + }; + + std::string source_; + std::string xpsFile_; + std::vector iFrameFile_; + }; + struct BufferFormatInfo { + OHOS::HDI::Display::Composer::V1_2::PixelFormat format = OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_BUTT; + std::string desc = "unknow"; + }; +private: + static constexpr int MAX_PATH_LEN = 256; + static constexpr char DUMP_PATH[] = "/data/log/imagecodecdump"; + CommandOpt decodeOpt_; + BufferFormatInfo outputFormat_; + OHOS::HDI::Codec::Image::V2_1::CodecHeifDecInfo decInfo_; +}; +} // OHOS::VDI::HEIF +#endif // OHOS_HDI_CODEC_IMAGE_V2_1_CODEC_HEIF_DECODE_HELPER \ No newline at end of file diff --git a/codec/test/demo/heif/include/command_parser.h b/codec/test/demo/heif/include/command_parser.h index 0f9ca75ba7..36079ae97c 100644 --- a/codec/test/demo/heif/include/command_parser.h +++ b/codec/test/demo/heif/include/command_parser.h @@ -33,7 +33,39 @@ enum class ImageRotation { NONE }; +enum class SampleSize { + SAMPLE_SIZE_1 = 1, + SAMPLE_SIZE_2 = 2, + SAMPLE_SIZE_4 = 4, + SAMPLE_SIZE_8 = 8, + SAMPLE_SIZE_16 = 16, +}; + +enum class UserPixelFormat { + NV12 = 0, + NV21, + NV12_10BIT, + NV21_10BIT, + RGBA8888, + BGRA8888, + RGB565, + RGBA1010102, + NONE +}; + +enum class ColorSpace { + BT_601_P, + BT_601_N, + P3, + BT_709, + BT_2020 +}; + struct CommandOpt { + // common + bool isGetHelpInfoOnly = false; + bool isEncoder = true; + // for encoder std::string primaryImgPath = ""; std::string auxiliaryImgPath = ""; std::string thumbnailImgPath = ""; @@ -45,8 +77,16 @@ struct CommandOpt { std::string outputPath = "/storage/media/100/local/files/heif_edit_dump"; ImageMirror mirrorInfo = ImageMirror::NONE; ImageRotation rotateInfo = ImageRotation::NONE; + // for decoder + std::string inputPath = ""; + SampleSize sampleSize = SampleSize::SAMPLE_SIZE_1; + UserPixelFormat pixelFmt = UserPixelFormat::NV12; + bool isLimitedRange = true; + ColorSpace colorSpace = ColorSpace::BT_601_P; void Print() const; + void PrintEncoderParam() const; + void PrintDecoderParam() const; }; CommandOpt Parse(int argc, char *argv[]); diff --git a/codec/test/demo/heif/src/codec_heif_decode_helper.cpp b/codec/test/demo/heif/src/codec_heif_decode_helper.cpp new file mode 100644 index 0000000000..07a083004b --- /dev/null +++ b/codec/test/demo/heif/src/codec_heif_decode_helper.cpp @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "surface_buffer.h" +#include "v2_0/cm_color_space.h" +#include "v2_0/buffer_handle_meta_key_type.h" +#include "log.h" +#include "syspara/parameters.h" +#include "codec_heif_decode_helper.h" + +namespace OHOS::VDI::HEIF { +using namespace std; +using namespace OHOS::HDI::Codec::Image::V2_1; +using namespace OHOS::HDI::Display::Graphic::Common::V2_0; + +void HeifDecoderHelper::InputParser::SplitString(const std::string& src, char sep, std::vector& vec) +{ + vec.clear(); + string::size_type startPos = 0; + while (true) { + string::size_type endPos = src.find_first_of(sep, startPos); + if (endPos == string::npos) { + break; + } + vec.emplace_back(src.substr(startPos, endPos - startPos)); + startPos = endPos + 1; + } + if (startPos != string::npos) { + vec.emplace_back(src.substr(startPos)); + } +} + +std::string HeifDecoderHelper::InputParser::JoinPath(const std::string& base, const std::string& append) +{ + return (filesystem::path(base) / append).string(); +} + +bool HeifDecoderHelper::InputParser::ParseGridInfo(GridInfo& gridInfo) +{ + // source_ demo: + // 1. has grid: 3072x4096_grid_512x512_6x8 + // 2. no grid: 3072x4096_nogrid + string baseDir = filesystem::path(source_).filename().string(); + vector vec; + SplitString(baseDir, MAIN_SEP, vec); + IF_TRUE_RETURN_VAL_WITH_MSG(vec.size() < MIN_MAIN_SEG_CNT, false, + "invalid source: %{public}s", source_.c_str()); + + vector vecTmp; + SplitString(vec[DISPLAY_SIZE], SUB_SEP, vecTmp); + IF_TRUE_RETURN_VAL_WITH_MSG(vecTmp.size() != SUB_SEG_CNT, false, "invalid source: %{public}s", source_.c_str()); + gridInfo.displayWidth = static_cast(stol(vecTmp[HORIZONTAL].c_str())); + gridInfo.displayHeight = static_cast(stol(vecTmp[VERTICAL].c_str())); + + if (vec[GRID_FLAG].find(NO_GRID_INDICATOR) != string::npos) { + gridInfo.enableGrid = false; + gridInfo.cols = 1; + gridInfo.rows = 1; + gridInfo.tileWidth = gridInfo.displayWidth; + gridInfo.tileHeight = gridInfo.displayHeight; + } else { + IF_TRUE_RETURN_VAL_WITH_MSG(vec.size() < MAX_MAIN_SEG_CNT, false, + "invalid source: %{public}s", source_.c_str()); + + gridInfo.enableGrid = true; + + SplitString(vec[TILE_SIZE], SUB_SEP, vecTmp); + IF_TRUE_RETURN_VAL_WITH_MSG(vecTmp.size() != SUB_SEG_CNT, false, + "invalid source: %{public}s", source_.c_str()); + gridInfo.tileWidth = static_cast(stol(vecTmp[HORIZONTAL].c_str())); + gridInfo.tileHeight = static_cast(stol(vecTmp[VERTICAL].c_str())); + + SplitString(vec[GRID_SIZE], SUB_SEP, vecTmp); + IF_TRUE_RETURN_VAL_WITH_MSG(vecTmp.size() != SUB_SEG_CNT, false, + "invalid source: %{public}s", source_.c_str()); + gridInfo.cols = static_cast(stol(vecTmp[HORIZONTAL].c_str())); + gridInfo.rows = static_cast(stol(vecTmp[VERTICAL].c_str())); + } + return true; +} + +void HeifDecoderHelper::InputParser::FindXpsAndIFrameFile() +{ + DIR *dirp = opendir(source_.c_str()); + IF_TRUE_RETURN_WITH_MSG(dirp == nullptr, "failed to open: %{public}s, errno=%{public}d", + source_.c_str(), errno); + struct dirent *dp; + while ((dp = readdir(dirp)) != nullptr) { + if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { + continue; + } + string path = JoinPath(source_, dp->d_name); + struct stat st{}; + if (stat(path.c_str(), &st) != 0 || !S_ISREG(st.st_mode)) { + continue; + } + string fileName(dp->d_name); + if (fileName.find(XPS_INDICATOR) != string::npos) { + xpsFile_ = path; + } else if (fileName.find(I_FRAME_INDICATOR) != string::npos) { + iFrameFile_.emplace_back(path); + } + } + closedir(dirp); +} + +bool HeifDecoderHelper::InputParser::ReadFileToAshmem(const string& filePath, vector>& inputs) +{ + ifstream ifs(filePath, ios::binary); + IF_TRUE_RETURN_VAL_WITH_MSG(!ifs.is_open(), false, "failed to open file: %{public}s", filePath.c_str()); + + ifs.seekg(0, ifstream::end); + size_t fileSize = static_cast(ifs.tellg()); + ifs.seekg(0, ifstream::beg); + + sptr ashmem = Ashmem::CreateAshmem(filePath.c_str(), static_cast(fileSize)); + IF_TRUE_RETURN_VAL_WITH_MSG(ashmem == nullptr, false, "failed to create ashmem for %{public}s, size(%{public}zu)", + filePath.c_str(), fileSize); + int fd = ashmem->GetAshmemFd(); + void* addr = ::mmap(nullptr, static_cast(fileSize), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + IF_TRUE_RETURN_VAL_WITH_MSG(addr == nullptr, false, "failed to map ashmem for %{public}s, size(%{public}zu)", + filePath.c_str(), fileSize); + ifs.read(reinterpret_cast(addr), static_cast(fileSize)); + ifs.close(); + ::munmap(addr, static_cast(fileSize)); + inputs.emplace_back(ashmem); + return true; +} + +int HeifDecoderHelper::InputParser::ExtractIFrameNum(const string& filePath) +{ + string fileName = filesystem::path(filePath).filename().string(); + string::size_type pos = fileName.find(I_FRAME_INDICATOR); + if (pos == string::npos) { + return -1; + } + return stoi(fileName.substr(pos + string(I_FRAME_INDICATOR).size())); +} + +bool HeifDecoderHelper::InputParser::ReadInput(vector>& inputs) +{ + FindXpsAndIFrameFile(); + IF_TRUE_RETURN_VAL_WITH_MSG(xpsFile_.empty(), false, "no xps file in %{public}s", source_.c_str()); + IF_TRUE_RETURN_VAL_WITH_MSG(iFrameFile_.empty(), false, "no iframe file in %{public}s", source_.c_str()); + + IF_TRUE_RETURN_VAL_WITH_MSG(!ReadFileToAshmem(xpsFile_, inputs), false, + "failed to read xps file: %{public}s", xpsFile_.c_str()); + std::sort(iFrameFile_.begin(), iFrameFile_.end(), [](const string& a, const string& b) { + return ExtractIFrameNum(a) < ExtractIFrameNum(b); + }); + for (const string& one : iFrameFile_) { + IF_TRUE_RETURN_VAL_WITH_MSG(!ReadFileToAshmem(one, inputs), false, + "failed to read iframe file: %{public}s", one.c_str()); + } + return true; +} + +static bool IsValueInRange(uint32_t value, uint32_t maxValue, uint32_t minValue) +{ + return (value >= minValue) && (value <= maxValue); +} + +bool HeifDecoderHelper::IsHeifHardwareDecodeSupported(sptr& hdiHeifDecoder) +{ + std::vector capList; + auto ret = hdiHeifDecoder->GetImageCapability(capList); + IF_TRUE_RETURN_VAL(ret != HDF_SUCCESS, false); + for (const CodecImageCapability& one : capList) { + if (one.role != CODEC_IMAGE_HEIF || one.type != CODEC_IMAGE_TYPE_DECODER) { + continue; + } + uint32_t widthToCheck = decInfo_.gridInfo.enableGrid ? + decInfo_.gridInfo.tileWidth : + decInfo_.gridInfo.displayWidth; + uint32_t heightToCheck = decInfo_.gridInfo.enableGrid ? + decInfo_.gridInfo.tileHeight : + decInfo_.gridInfo.displayHeight; + if (IsValueInRange(widthToCheck, one.maxWidth, one.minWidth) && + IsValueInRange(heightToCheck, one.maxHeight, one.minHeight)) { + return true; + } + if (IsValueInRange(widthToCheck, one.maxHeight, one.minHeight) && + IsValueInRange(heightToCheck, one.maxWidth, one.minWidth)) { + return true; + } + } + return false; +} + +void HeifDecoderHelper::DoDecode() +{ + cout << "start heif decode" << endl; + IF_TRUE_RETURN_WITH_MSG(!GetOutputFormat(), "failed to get output format"); + std::vector> inputs; + IF_TRUE_RETURN_WITH_MSG(!ReadInput(inputs), "failed to read input"); + GetSampleSize(); + sptr output; + IF_TRUE_RETURN_WITH_MSG(!AllocateOutputBuffer(output), "failed to allocate output buffer"); + sptr hdiHeifDecoder = ICodecImage::Get(); + IF_TRUE_RETURN_WITH_MSG(hdiHeifDecoder == nullptr, "failed to get ICodecImage"); + IF_TRUE_RETURN_WITH_MSG(!IsHeifHardwareDecodeSupported(hdiHeifDecoder), "heif hw decode not supported"); + int32_t ret = hdiHeifDecoder->DoHeifDecode(inputs, output, decInfo_); + if (ret == HDF_SUCCESS) { + cout << "heif decode succeed" << endl; + if (OHOS::system::GetBoolParameter("hdi.image.heif.decode.dump", false)) { + DumpOutput(output); + } + } else { + cout << "heif decode failed" << endl; + } +} + +bool HeifDecoderHelper::GetOutputFormat() +{ + static const map pixelFmtMap = { + { UserPixelFormat::NV12, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP }, + { UserPixelFormat::NV21, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCRCB_420_SP }, + { UserPixelFormat::NV12_10BIT, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_P010 }, + { UserPixelFormat::NV21_10BIT, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCRCB_P010 }, + { UserPixelFormat::RGBA8888, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGBA_8888 }, + { UserPixelFormat::BGRA8888, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_BGRA_8888 }, + { UserPixelFormat::RGB565, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGB_565 }, + { UserPixelFormat::RGBA1010102, OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGBA_1010102 }, + }; + auto iterFmt = pixelFmtMap.find(decodeOpt_.pixelFmt); + IF_TRUE_RETURN_VAL_WITH_MSG(iterFmt == pixelFmtMap.end(), false, + "unsupported pixel format: %{public}d", static_cast(decodeOpt_.pixelFmt)); + outputFormat_.format = iterFmt->second; + + static const map pixelFmtDescMap = { + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP, "NV12" }, + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCRCB_420_SP, "NV21" }, + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_P010, "NV12_10BIT" }, + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCRCB_P010, "NV21_10BIT" }, + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGBA_8888, "RGBA8888" }, + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_BGRA_8888, "BGRA8888" }, + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGB_565, "RGB565" }, + { OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_RGBA_1010102, "RGBA1010102"}, + }; + auto iterDesc = pixelFmtDescMap.find(outputFormat_.format); + IF_TRUE_RETURN_VAL_WITH_MSG(iterDesc == pixelFmtDescMap.end(), false, + "unsupported pixel format: %{public}d", static_cast(decodeOpt_.pixelFmt)); + outputFormat_.desc = iterDesc->second; + return true; +} + +bool HeifDecoderHelper::ReadInput(vector>& inputs) +{ + InputParser parser(decodeOpt_.inputPath); + bool ret = parser.ParseGridInfo(decInfo_.gridInfo); + ret = ret && parser.ReadInput(inputs); + return ret; +} + +void HeifDecoderHelper::GetMetaDataInfo(CM_ColorSpaceInfo& colorSpaceInfo) +{ + colorSpaceInfo.range = (decodeOpt_.isLimitedRange)? RANGE_LIMITED : RANGE_FULL; + static const map colorSpaceDescMap = { + { ColorSpace::BT_601_P, MATRIX_BT601_P }, + { ColorSpace::BT_601_N, MATRIX_BT601_N }, + { ColorSpace::P3, MATRIX_P3 }, + { ColorSpace::BT_709, MATRIX_BT709 }, + { ColorSpace::BT_2020, MATRIX_BT2020 }, + }; + + auto iterDesc = colorSpaceDescMap.find(decodeOpt_.colorSpace); + if (iterDesc == colorSpaceDescMap.end()) { + HDF_LOGE("unsupported colorSpace: %{public}d", static_cast(decodeOpt_.colorSpace)); + colorSpaceInfo.matrix = MATRIX_BT601_P; + return; + } + + colorSpaceInfo.matrix = iterDesc->second; + return; +} + +bool HeifDecoderHelper::AllocateOutputBuffer(sptr& output) +{ + uint64_t usage = BUFFER_USAGE_CPU_READ | + BUFFER_USAGE_CPU_WRITE | + BUFFER_USAGE_MEM_DMA | + BUFFER_USAGE_MEM_MMZ_CACHE; + + sptr surfaceBuffer = SurfaceBuffer::Create(); + IF_TRUE_RETURN_VAL_WITH_MSG(surfaceBuffer == nullptr, false, "failed to create buffer\n"); + + BufferRequestConfig config = { + .width = decInfo_.gridInfo.displayWidth / decInfo_.sampleSize, + .height = decInfo_.gridInfo.displayHeight / decInfo_.sampleSize, + .strideAlignment = 32, + .format = outputFormat_.format, + .usage = usage, + .timeout = 0 + }; + + GSError ret = surfaceBuffer->Alloc(config); + IF_TRUE_RETURN_VAL_WITH_MSG(ret != GSERROR_OK, false, "failed to alloc surfaceBuffer, ret=%{public}d\n", ret); + + CM_ColorSpaceInfo colorSpaceInfo = {}; + GetMetaDataInfo(colorSpaceInfo); + surfaceBuffer->SetMetadata(ATTRKEY_COLORSPACE_INFO, Pod2Vec(colorSpaceInfo)); + + output = new NativeBuffer(surfaceBuffer->GetBufferHandle()); + + return true; +} + +static int64_t GetTimestampInMs() +{ + auto now = chrono::steady_clock::now(); + return chrono::duration_cast(now.time_since_epoch()).count(); +} + +void HeifDecoderHelper::DumpOutput(sptr& output) +{ + cout << "dump heif decode result" << endl; + sptr outputSurface = SurfaceBuffer::Create(); + IF_TRUE_RETURN_WITH_MSG(outputSurface == nullptr, "output is null"); + outputSurface->SetBufferHandle(output->Move()); + int64_t timestamp = GetTimestampInMs(); + char outputFilePath[MAX_PATH_LEN] = {0}; + int ret = 0; + if (decInfo_.gridInfo.enableGrid) { + ret = sprintf_s(outputFilePath, sizeof(outputFilePath), + "%s/%ld_hdiout_%s_%u(%d)x%u(%d)_grid_%ux%u_%ux%u_s%u_m%d_r%d.bin", + DUMP_PATH, timestamp, outputFormat_.desc.c_str(), + decInfo_.gridInfo.displayWidth, outputSurface->GetStride(), + decInfo_.gridInfo.displayHeight, outputSurface->GetHeight(), + decInfo_.gridInfo.tileWidth, decInfo_.gridInfo.tileHeight, + decInfo_.gridInfo.cols, decInfo_.gridInfo.rows, decInfo_.sampleSize, + static_cast(decodeOpt_.colorSpace), decodeOpt_.isLimitedRange); + } else { + ret = sprintf_s(outputFilePath, sizeof(outputFilePath), + "%s/%ld_hdiout_%s_%u(%d)x%u(%d)_nogrid_s%u_m%d_r%d.bin", + DUMP_PATH, timestamp, outputFormat_.desc.c_str(), + decInfo_.gridInfo.displayWidth, outputSurface->GetStride(), + decInfo_.gridInfo.displayHeight, outputSurface->GetHeight(), + decInfo_.sampleSize, static_cast(decodeOpt_.colorSpace), + decodeOpt_.isLimitedRange); + } + if (ret == -1) { + HDF_LOGE("failed to create dump file"); + return; + } + cout << "dump result to: " << outputFilePath << endl; + + std::ofstream dumpOutFile; + dumpOutFile.open(std::string(outputFilePath), std::ios_base::binary | std::ios_base::trunc); + if (!dumpOutFile.is_open()) { + cout << "failed to dump decode result" << endl; + return; + } + + GSError err = outputSurface->InvalidateCache(); + if (err != GSERROR_OK) { + cout << "InvalidateCache failed, GSError=" << err << endl; + } + dumpOutFile.write(reinterpret_cast(outputSurface->GetVirAddr()), outputSurface->GetSize()); + dumpOutFile.close(); +} + +void HeifDecoderHelper::GetSampleSize() +{ + static const map sampleSizeMap = { + { SampleSize::SAMPLE_SIZE_1, 1 }, + { SampleSize::SAMPLE_SIZE_2, 2 }, + { SampleSize::SAMPLE_SIZE_4, 4 }, + { SampleSize::SAMPLE_SIZE_8, 8 }, + { SampleSize::SAMPLE_SIZE_16, 16 }, + }; + auto iter = sampleSizeMap.find(decodeOpt_.sampleSize); + if (iter != sampleSizeMap.end()) { + decInfo_.sampleSize = iter->second; + } else { + decInfo_.sampleSize = 1; + } +} +} \ No newline at end of file diff --git a/codec/test/demo/heif/src/command_parser.cpp b/codec/test/demo/heif/src/command_parser.cpp index 3507f4ac5d..bef5140a5b 100644 --- a/codec/test/demo/heif/src/command_parser.cpp +++ b/codec/test/demo/heif/src/command_parser.cpp @@ -15,6 +15,7 @@ #include #include +#include #include "command_parser.h" namespace OHOS::VDI::HEIF { @@ -33,7 +34,13 @@ enum ShortOption { OPT_IT35, OPT_MIRROR, OPT_ROTATE, - OPT_OUTPUT = 'o' + OPT_OUTPUT = 'o', + OPT_INPUT_PATH = 'i', + OPT_SAMPLE_SIZE, + OPT_PIXEL_FMT, + OPT_IS_ENCODER, + OPT_IS_LIMITED_RANGE, + OPT_COLORSPACE }; static struct option g_longOptions[] = { @@ -49,14 +56,24 @@ static struct option g_longOptions[] = { {"mirror", required_argument, nullptr, static_cast(ShortOption::OPT_MIRROR)}, {"rotate", required_argument, nullptr, static_cast(ShortOption::OPT_ROTATE)}, {"out", required_argument, nullptr, static_cast(ShortOption::OPT_OUTPUT)}, + {"inputPath", required_argument, nullptr, static_cast(ShortOption::OPT_INPUT_PATH)}, + {"sampleSize", required_argument, nullptr, static_cast(ShortOption::OPT_SAMPLE_SIZE)}, + {"pixelFmt", required_argument, nullptr, static_cast(ShortOption::OPT_PIXEL_FMT)}, + {"isEncoder", required_argument, nullptr, static_cast(ShortOption::OPT_IS_ENCODER)}, + {"isLimitedRange", required_argument, nullptr, static_cast(ShortOption::OPT_IS_LIMITED_RANGE)}, + {"colorSpace", required_argument, nullptr, static_cast(ShortOption::OPT_COLORSPACE)}, {nullptr, no_argument, nullptr, static_cast(ShortOption::OPT_UNKONWN)}, }; void ShowUsage() { std::string rotateValueOpt = "0: ANTI_CLOCKWISE_90, 1: ANTI_CLOCKWISE_180, 2: ANTI_CLOCKWISE_270"; - std::cout << "Heif Hardware encode Demo Options:" << std::endl; + std::string pixelFmtValueOpt = "0:NV12(default), 1:NV21, 2:NV12_10BIT, 3:NV21_10BIT, " \ + "4:RGBA8888, 5:BGRA8888, 6:RGB565, 7:RGBA1010102"; + std::string colorSpaceOpt = "0: BT_601_P(default), 1: BT_601_N, 2: P3, 3: BT_709, 4: BT_2020"; std::cout << " --help help info." << std::endl; + std::cout << " --isEncoder codec type. 0: decoder, 1: encoder" << std::endl; + std::cout << "Heif Hardware encode Demo Options:" << std::endl; std::cout << " --primaryImg full path for primary image file." << std::endl; std::cout << " --auxiliaryImg (optional) full path for auxiliary image file." << std::endl; std::cout << " --thumbnailImg (optional) full path for thumbnail image file." << std::endl; @@ -67,59 +84,104 @@ void ShowUsage() std::cout << " --it35 (optional) full path for it35 file." << std::endl; std::cout << " --mirror (optional) image mirror info. 0: HORIZONTAL, 1: VERTICAL" << std::endl; std::cout << " --rotate (optional) image rotate info. " << rotateValueOpt << std::endl; - std::cout << " -o, --out (optional) full path for output file." << std::endl; + std::cout << " -o, --out full path for output file." << std::endl; + std::cout << "Heif Hardware decode Demo Options:" << std::endl; + std::cout << " -i, --inputPath full path for input." << std::endl; + std::cout << " --sampleSize (optional) output sample size. options: 2/4/8/16" << std::endl; + std::cout << " --pixelFmt (optional) output pixel format. " << pixelFmtValueOpt << std::endl; + std::cout << " --isLimitedRange (optional) range flag. 0: full range, 1: limited range" << std::endl; + std::cout << " --colorSpace (optional) color space type. " << colorSpaceOpt << std::endl; +} + +static void AnalyzeParamForEncoder(ShortOption c, CommandOpt& opt) +{ + switch (c) { + case ShortOption::OPT_PRIMARY_IMG: + opt.primaryImgPath = string(optarg); + break; + case ShortOption::OPT_AUXILIARY_IMG: + opt.auxiliaryImgPath = string(optarg); + break; + case ShortOption::OPT_THUMBNAIL_IMG: + opt.thumbnailImgPath = string(optarg); + break; + case ShortOption::OPT_GAIN_MAP: + opt.gainMapPath = string(optarg); + break; + case ShortOption::OPT_EXIF_DATA: + opt.exifDataPath = string(optarg); + break; + case ShortOption::OPT_USER_DATA: + opt.userDataPath = string(optarg); + break; + case ShortOption::OPT_ICC_PROFILE: + opt.iccProfilePath = string(optarg); + break; + case ShortOption::OPT_IT35: + opt.it35Path = string(optarg); + break; + case ShortOption::OPT_MIRROR: + opt.mirrorInfo = static_cast(stol(optarg)); + break; + case ShortOption::OPT_ROTATE: + opt.rotateInfo = static_cast(stol(optarg)); + break; + case ShortOption::OPT_OUTPUT: + opt.outputPath = string(optarg); + break; + default: + break; + } +} + +static void AnalyzeParamForDecoder(ShortOption c, CommandOpt& opt) +{ + switch (c) { + case ShortOption::OPT_INPUT_PATH: + opt.inputPath = string(optarg); + break; + case ShortOption::OPT_SAMPLE_SIZE: + opt.sampleSize = static_cast(stol(optarg)); + break; + case ShortOption::OPT_PIXEL_FMT: + opt.pixelFmt = static_cast(stol(optarg)); + break; + case ShortOption::OPT_IS_LIMITED_RANGE: + opt.isLimitedRange = (stol(optarg) != 0); + break; + case ShortOption::OPT_COLORSPACE: + opt.colorSpace = static_cast(stol(optarg)); + break; + default: + break; + } } CommandOpt Parse(int argc, char *argv[]) { CommandOpt opt; int c; - while ((c = getopt_long(argc, argv, "o:", g_longOptions, nullptr)) != -1) { + while ((c = getopt_long(argc, argv, "o:i:", g_longOptions, nullptr)) != -1) { switch (static_cast(c)) { case ShortOption::OPT_HELP: ShowUsage(); + opt.isGetHelpInfoOnly = true; break; - case ShortOption::OPT_PRIMARY_IMG: - opt.primaryImgPath = string(optarg); - break; - case ShortOption::OPT_AUXILIARY_IMG: - opt.auxiliaryImgPath = string(optarg); - break; - case ShortOption::OPT_THUMBNAIL_IMG: - opt.thumbnailImgPath = string(optarg); - break; - case ShortOption::OPT_GAIN_MAP: - opt.gainMapPath = string(optarg); - break; - case ShortOption::OPT_EXIF_DATA: - opt.exifDataPath = string(optarg); - break; - case ShortOption::OPT_USER_DATA: - opt.userDataPath = string(optarg); - break; - case ShortOption::OPT_ICC_PROFILE: - opt.iccProfilePath = string(optarg); - break; - case ShortOption::OPT_IT35: - opt.it35Path = string(optarg); - break; - case ShortOption::OPT_MIRROR: - opt.mirrorInfo = static_cast(stol(optarg)); - break; - case ShortOption::OPT_ROTATE: - opt.rotateInfo = static_cast(stol(optarg)); - break; - case ShortOption::OPT_OUTPUT: - opt.outputPath = string(optarg); + case ShortOption::OPT_IS_ENCODER: + opt.isEncoder = (stol(optarg) != 0); break; default: break; } + if (!opt.isGetHelpInfoOnly) { + AnalyzeParamForEncoder(static_cast(c), opt); + AnalyzeParamForDecoder(static_cast(c), opt); + } } return opt; } -static string GetMirrorPrintInfo(ImageMirror info) +static string GetMirrorPrintInfo(const ImageMirror& info) { if (info == ImageMirror::NONE) { return "ImageMirror::NONE"; @@ -133,7 +195,7 @@ static string GetMirrorPrintInfo(ImageMirror info) return "unknown mirror info"; } -static string GetRotatePrintInfo(ImageRotation info) +static string GetRotatePrintInfo(const ImageRotation& info) { if (info == ImageRotation::NONE) { return "ImageRotation::NONE"; @@ -150,7 +212,7 @@ static string GetRotatePrintInfo(ImageRotation info) return "unknown rotate info"; } -void CommandOpt::Print() const +void CommandOpt::PrintEncoderParam() const { std::cout << "=========================== OPT INFO ===========================" << endl; std::cout << " primaryImgPath : " << primaryImgPath << endl; @@ -166,4 +228,76 @@ void CommandOpt::Print() const std::cout << " outputPath : " << outputPath << endl; std::cout << "=================================================================" << endl; } + +static string GetSampleSizePrintInfo(const SampleSize& info) +{ + static const map sampleSizeMap = { + { SampleSize::SAMPLE_SIZE_1, "1" }, + { SampleSize::SAMPLE_SIZE_2, "2" }, + { SampleSize::SAMPLE_SIZE_4, "4" }, + { SampleSize::SAMPLE_SIZE_8, "8" }, + { SampleSize::SAMPLE_SIZE_16, "16" }, + }; + auto iter = sampleSizeMap.find(info); + if (iter != sampleSizeMap.end()) { + return iter->second; + } + return "unknown sample size"; +} + +static string GetPixelFmtPrintInfo(const UserPixelFormat& info) +{ + static const map pixelFmtMap = { + { UserPixelFormat::NONE, "UserPixelFormat::NONE" }, + { UserPixelFormat::NV12, "UserPixelFormat::NV12" }, + { UserPixelFormat::NV21, "UserPixelFormat::NV21" }, + { UserPixelFormat::NV12_10BIT, "UserPixelFormat::NV12_10BIT" }, + { UserPixelFormat::NV21_10BIT, "UserPixelFormat::NV21_10BIT" }, + { UserPixelFormat::RGBA8888, "UserPixelFormat::RGBA8888" }, + { UserPixelFormat::BGRA8888, "UserPixelFormat::BRGA8888" }, + { UserPixelFormat::RGB565, "UserPixelFormat::RGB565" }, + { UserPixelFormat::RGBA1010102, "UserPixelFormat::RGBA1010102" }, + }; + auto iter = pixelFmtMap.find(info); + if (iter != pixelFmtMap.end()) { + return iter->second; + } + return "unknown pixel format"; +} + +static string GetColorSpacePrintInfo(const ColorSpace& info) +{ + static const map colorSpaceMap = { + { ColorSpace::BT_601_P, "ColorSpace::BT_601_P" }, + { ColorSpace::BT_601_N, "ColorSpace::BT_601_N" }, + { ColorSpace::P3, "ColorSpace::P3" }, + { ColorSpace::BT_709, "ColorSpace::BT_709" }, + { ColorSpace::BT_2020, "ColorSpace::BT_2020" }, + }; + auto iter = colorSpaceMap.find(info); + if (iter != colorSpaceMap.end()) { + return iter->second; + } + return "unknown color space, use ColorSpace::BT_601_P as default"; +} + +void CommandOpt::PrintDecoderParam() const +{ + std::cout << "=========================== OPT INFO ===========================" << endl; + std::cout << " inputPath : " << inputPath << endl; + std::cout << " sampleSize : " << GetSampleSizePrintInfo(sampleSize) << endl; + std::cout << " pixelFmt : " << GetPixelFmtPrintInfo(pixelFmt) << endl; + std::cout << " colorSpace : " << GetColorSpacePrintInfo(colorSpace) << endl; + std::cout << " range : " << (isLimitedRange ? "limited range" : "full range") << endl; + std::cout << "=================================================================" << endl; +} + +void CommandOpt::Print() const +{ + if (isEncoder) { + PrintEncoderParam(); + } else { + PrintDecoderParam(); + } +} } diff --git a/codec/test/demo/heif/src/heif_decoder.cpp b/codec/test/demo/heif/src/heif_decoder.cpp new file mode 100644 index 0000000000..94632918ea --- /dev/null +++ b/codec/test/demo/heif/src/heif_decoder.cpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "codec_heif_decode_helper.h" + +int main(int argc, char *argv[]) +{ + OHOS::VDI::HEIF::CommandOpt opt = OHOS::VDI::HEIF::Parse(argc, argv); + if (!opt.isGetHelpInfoOnly) { + opt.Print(); + OHOS::VDI::HEIF::HeifDecoderHelper obj(opt); + obj.DoDecode(); + } + return 0; +} \ No newline at end of file diff --git a/codec/test/demo/heif/src/heif_encoder.cpp b/codec/test/demo/heif/src/heif_encoder.cpp index 1dbffd8578..2e83fb6a3a 100644 --- a/codec/test/demo/heif/src/heif_encoder.cpp +++ b/codec/test/demo/heif/src/heif_encoder.cpp @@ -18,8 +18,10 @@ int main(int argc, char *argv[]) { OHOS::VDI::HEIF::CommandOpt opt = OHOS::VDI::HEIF::Parse(argc, argv); - opt.Print(); - OHOS::VDI::HEIF::HeifEncoderHelper obj(opt); - obj.DoEncode(); + if (!opt.isGetHelpInfoOnly) { + opt.Print(); + OHOS::VDI::HEIF::HeifEncoderHelper obj(opt); + obj.DoEncode(); + } return 0; } \ No newline at end of file diff --git a/codec/test/fuzztest/image_fuzzer/BUILD.gn b/codec/test/fuzztest/image_fuzzer/BUILD.gn index c03bcf54ca..c3ed7f72e4 100644 --- a/codec/test/fuzztest/image_fuzzer/BUILD.gn +++ b/codec/test/fuzztest/image_fuzzer/BUILD.gn @@ -17,6 +17,7 @@ group("hdf_image_fuzz_test") { testonly = true deps = [ "imageallocateinbuffer_fuzzer:fuzztest", + "imagedoheifdecode_fuzzer:fuzztest", "imagedoheifencode_fuzzer:fuzztest", "imagedojpegdecode_fuzzer:fuzztest", "imagefreeinbuffer_fuzzer:fuzztest", diff --git a/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/BUILD.gn b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/BUILD.gn new file mode 100644 index 0000000000..665cef4247 --- /dev/null +++ b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/BUILD.gn @@ -0,0 +1,63 @@ +# Copyright (c) 2024 Shenzhen Kaihong DID Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/config/features.gni") +import("//build/test.gni") +module_output_path = "drivers_peripheral_codec/drivers_peripheral_codec" + +ohos_fuzztest("ImageDoHeifDecodeFuzzTest") { + module_out_path = module_output_path + codec_root = "../../../../" + fuzz_config_file = + "${codec_root}/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer" + + include_dirs = [ + "${codec_root}/test/fuzztest/image_fuzzer/common/include", + "${codec_root}/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer", + ] + + external_deps = [ + "c_utils:utils", + "drivers_interface_codec:libimage_proxy_2.1", + "drivers_interface_display:libdisplay_buffer_proxy_1.0", + "drivers_interface_display:libdisplay_buffer_proxy_1.2", + "drivers_interface_display:libdisplay_composer_proxy_1.0", + "drivers_interface_display:libdisplay_composer_proxy_1.1", + "drivers_interface_display:libdisplay_composer_proxy_1.2", + "drivers_interface_display:libdisplay_buffer_hdi_impl_v1_2", + "drivers_interface_display:libdisplay_composer_hdi_impl_1.2", + "hdf_core:libhdf_host", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hdf_core:libhdi", + "hilog:libhilog", + "ipc:ipc_single", + ] + + cflags = [ + "-g", + "-O0", + "-Wno-unused-variable", + "-fno-omit-frame-pointer", + ] + + sources = [ + "imagedoheifdecode_fuzzer.cpp", + ] +} + +group("fuzztest") { + testonly = true + deps = [] + deps += [ ":ImageDoHeifDecodeFuzzTest" ] +} diff --git a/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/corpus/init b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/corpus/init new file mode 100644 index 0000000000..0db7271ce7 --- /dev/null +++ b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/corpus/init @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Shenzhen Kaihong DID Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FUZZ diff --git a/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.cpp b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.cpp new file mode 100644 index 0000000000..320e4b4ab5 --- /dev/null +++ b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.cpp @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "ashmem.h" +#include "v2_1/icodec_image.h" +#include "v1_2/display_composer_type.h" +#include "v1_2/display_buffer_type.h" +#include "v1_2/include/idisplay_buffer.h" +#include "imagedoheifdecode_fuzzer.h" + +using namespace OHOS::HDI::Codec::Image::V2_1; +using namespace OHOS::HDI::Display::Buffer::V1_2; +using namespace OHOS::HDI::Display::Composer::V1_2; +using namespace OHOS; +using namespace std; +namespace OHOS { +namespace Codec { +namespace Image { + +static uint32_t Convert2Uint32(const uint8_t *ptr) +{ + if (ptr == nullptr) { + return 0; + } + return (ptr[0] << 24) | (ptr[1] << 16) | // 24:bit offset, 16: bit offset, 1:byte offset + (ptr[2] << 8) | (ptr[3]); // 8:bit offset, 2: byte offset, 3:byte offset +} + +static sptr GetAshmem(const char *name, int32_t size) +{ + auto ashmem = Ashmem::CreateAshmem(name, size); + if (ashmem == nullptr) { + HDF_LOGE("%{public}s: ashmem init failed\n", __func__); + return ashmem; + } + if (!ashmem->MapReadAndWriteAshmem()) { + HDF_LOGE("%{public}s: ashmem map failed\n", __func__); + return ashmem; + } + return ashmem; +} + +static void CloseAshmem(sptr ashmem) +{ + if (ashmem != nullptr) { + ashmem->UnmapAshmem(); + ashmem->CloseAshmem(); + } +} + +static bool CreateAshmem(const CodecHeifDecInfo &decInfo, std::vector> &inputs, uint8_t *data, size_t size) +{ + static constexpr uint32_t XPS_CNT = 1; + uint32_t gridCnt = decInfo.gridInfo.enableGrid ? (decInfo.gridInfo.rows * decInfo.gridInfo.cols) : 1; + uint32_t inputSize = XPS_CNT + gridCnt; + for (uint32_t i = 0; i < inputSize; i++) { + int32_t asmSize = 4; + sptr asmptr = GetAshmem("fuzz_ashmem", asmSize); + if (asmptr == nullptr) { + return false; + } + int32_t len = (size > asmSize) ? asmSize : size; + if (!asmptr->WriteToAshmem(data, len, 0)) { + CloseAshmem(asmptr); + HDF_LOGE("%{public}s: writing ashmem failed\n", __func__); + return false; + } + + inputs.push_back(asmptr); + } + return true; +} + +static bool CreateNativeBuffer(sptr &output, const CodecHeifDecInfo &decInfo) +{ + OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer *bufferMgr = + OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer::Get(); + uint64_t usage = OHOS::HDI::Display::Composer::V1_2::HBM_USE_CPU_READ | + OHOS::HDI::Display::Composer::V1_2::HBM_USE_CPU_WRITE | + OHOS::HDI::Display::Composer::V1_2::HBM_USE_MEM_DMA; + AllocInfo alloc = {.width = decInfo.gridInfo.displayWidth, + .height = decInfo.gridInfo.displayHeight, + .usage = usage, + .format = OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP}; + BufferHandle *handle = nullptr; + int32_t ret = bufferMgr->AllocMem(alloc, handle); + if (ret != HDF_SUCCESS) { + return false; + } + output = new NativeBuffer(); + output->SetBufferHandle(handle, true); + return true; +} + +static uint32_t GetUInt32AndMove(uint8_t *data, uint8_t *¤tPos, size_t size) +{ + uint32_t value = Convert2Uint32(currentPos); + if ((currentPos + sizeof(uint32_t) + sizeof(uint32_t)) > (data + size)) { + currentPos = data; + } else { + currentPos += sizeof(uint32_t); + } + return value; +} + +static bool FillHeifDecInfo(CodecHeifDecInfo &decInfo, uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(uint32_t)) { + return false; + } + constexpr uint32_t SIZE_FACTOR = 8192; + constexpr uint32_t ROW_COL_FACTOR = 1024; + constexpr uint32_t SAMPLE_FACTOR = 20; + constexpr uint8_t EVEN_FACTOR = 2; + uint8_t *currentPos = data; + decInfo.gridInfo.displayWidth = GetUInt32AndMove(data, currentPos, size) % SIZE_FACTOR; + decInfo.gridInfo.displayHeight = GetUInt32AndMove(data, currentPos, size) % SIZE_FACTOR; + decInfo.gridInfo.enableGrid = *currentPos % EVEN_FACTOR; + decInfo.gridInfo.tileWidth = GetUInt32AndMove(data, currentPos, size) % SIZE_FACTOR; + decInfo.gridInfo.tileHeight = GetUInt32AndMove(data, currentPos, size) % SIZE_FACTOR; + decInfo.gridInfo.cols = GetUInt32AndMove(data, currentPos, size) % ROW_COL_FACTOR; + decInfo.gridInfo.rows = GetUInt32AndMove(data, currentPos, size) % ROW_COL_FACTOR; + decInfo.sampleSize = GetUInt32AndMove(data, currentPos, size) % SAMPLE_FACTOR; + + return true; +} + +bool DoHeifDecode(const uint8_t *data, size_t size) +{ + if (data == nullptr || size < sizeof(unsigned int)) { + return false; + } + + sptr image = ICodecImage::Get(false); + if (image == nullptr) { + HDF_LOGE("%{public}s: get ICodecImage failed\n", __func__); + return false; + } + CodecImageRole role = CodecImageRole(*data); + ImageAutoIniter autoIniter(image, role); + + uint8_t *rawData = const_cast(data); + + CodecHeifDecInfo decInfo; + if (!FillHeifDecInfo(decInfo, rawData, size)) { + return false; + } + + std::vector> inputs; + CreateAshmem(decInfo, inputs, rawData, size); + sptr output = nullptr; + CreateNativeBuffer(output, decInfo); + + auto err = image->DoHeifDecode(inputs, output, decInfo); + if (err != HDF_SUCCESS) { + HDF_LOGE("%{public}s: DoHeifDecode return %{public}d", __func__, err); + } + for (auto &input : inputs) { + CloseAshmem(input); + } + + return true; +} +} // namespace Image +} // namespace Codec +} // namespace OHOS + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + OHOS::Codec::Image::DoHeifDecode(data, size); + return 0; +} diff --git a/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.h b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.h new file mode 100644 index 0000000000..e8679840c6 --- /dev/null +++ b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/imagedoheifdecode_fuzzer.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef IMAGE_DO_HEIF_DECODE_FUZZER +#define IMAGE_DO_HEIF_DECODE_FUZZER + +#define FUZZ_PROJECT_NAME "imagedoheifdecode_fuzzer" + + +#endif diff --git a/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/project.xml b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/project.xml new file mode 100644 index 0000000000..e676bbe347 --- /dev/null +++ b/codec/test/fuzztest/image_fuzzer/imagedoheifdecode_fuzzer/project.xml @@ -0,0 +1,25 @@ + + + + + + 1000 + + 120 + + 2048 + + diff --git a/codec/test/unittest/hdi_image/BUILD.gn b/codec/test/unittest/hdi_image/BUILD.gn index 5ce5e213df..487432eb23 100644 --- a/codec/test/unittest/hdi_image/BUILD.gn +++ b/codec/test/unittest/hdi_image/BUILD.gn @@ -73,9 +73,42 @@ ohos_unittest("codec_hdi_heif_encode_test") { } } +ohos_unittest("codec_hdi_heif_decode_test") { + module_out_path = "drivers_peripheral_codec/codec" + + sources = [ "codec_hdi_heif_decode_test.cpp" ] + + if (is_standard_system) { + external_deps = [ + "c_utils:utils", + "drivers_interface_codec:libimage_proxy_2.1", + "drivers_interface_display:libdisplay_buffer_proxy_1.0", + "drivers_interface_display:libdisplay_buffer_proxy_1.2", + "drivers_interface_display:libdisplay_composer_proxy_1.0", + "drivers_interface_display:libdisplay_composer_proxy_1.1", + "drivers_interface_display:libdisplay_composer_proxy_1.2", + "drivers_interface_display:libdisplay_buffer_hdi_impl_v1_2", + "drivers_interface_display:libdisplay_composer_hdi_impl_1.2", + "hdf_core:libhdf_host", + "hdf_core:libhdf_ipc_adapter", + "hdf_core:libhdf_utils", + "hdf_core:libhdi", + "hilog:libhilog", + "ipc:ipc_single", + ] + } else { + external_deps = [ "hilog:libhilog" ] + } + defines = [] + if (drivers_peripheral_codec_feature_support_heif_test) { + defines += [ "SUPPORT_HEIF" ] + } +} + group("codec_hdi_image_test") { testonly = true deps = [ + ":codec_hdi_heif_decode_test", ":codec_hdi_heif_encode_test", ":codec_hdi_jpeg_test", ] diff --git a/codec/test/unittest/hdi_image/codec_hdi_heif_decode_test.cpp b/codec/test/unittest/hdi_image/codec_hdi_heif_decode_test.cpp new file mode 100644 index 0000000000..5d91581b11 --- /dev/null +++ b/codec/test/unittest/hdi_image/codec_hdi_heif_decode_test.cpp @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "hdf_log.h" +#include "ashmem.h" +#include "v2_1/icodec_image.h" +#include "v1_2/display_composer_type.h" +#include "v1_2/display_buffer_type.h" +#include "v1_2/include/idisplay_buffer.h" + +#define HDF_LOG_TAG codec_heif_decode_test + +namespace { +using namespace std; +using namespace testing::ext; +using namespace OHOS::HDI::Codec::Image::V2_1; +using namespace OHOS::HDI::Display::Buffer::V1_2; +using namespace OHOS::HDI::Display::Composer::V1_2; + +static OHOS::sptr hdiHeifDecoder_ = nullptr; +static OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer* bufferMgr_ = nullptr; + +class CodecHdiHeifDecodeTest : public testing::Test { +public: + static void SetUpTestCase() + { + hdiHeifDecoder_ = ICodecImage::Get(); + bufferMgr_ = OHOS::HDI::Display::Buffer::V1_2::IDisplayBuffer::Get(); + } + static void TearDownTestCase() + { + hdiHeifDecoder_ = nullptr; + bufferMgr_ = nullptr; + } + void SetUp() override + { + } + void TearDown() override + { + } + + sptr AllocateOutputBuffer(uint32_t width, uint32_t height, int32_t pixelFmt) + { + uint64_t usage = OHOS::HDI::Display::Composer::V1_2::HBM_USE_CPU_READ | + OHOS::HDI::Display::Composer::V1_2::HBM_USE_CPU_WRITE | + OHOS::HDI::Display::Composer::V1_2::HBM_USE_MEM_DMA | + OHOS::HDI::Display::Composer::V1_2::HBM_USE_MEM_MMZ_CACHE; + AllocInfo alloc = { + .width = width, + .height = height, + .usage = usage, + .format = pixelFmt + }; + BufferHandle *handle = nullptr; + int32_t ret = bufferMgr_->AllocMem(alloc, handle); + if (ret != HDF_SUCCESS || handle == nullptr) { + return nullptr; + } + sptr output = new NativeBuffer(handle); + return output; + } +public: +}; + +// [fail] output is null +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_001, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo {}; + sptr output = nullptr; + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] displaySize == 0 +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_002, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 0, + .displayHeight = 0, + .enableGrid = false, + .cols = 0, + .rows = 0, + .tileWidth = 0, + .tileHeight = 0 + }; + decInfo.sampleSize = 1; + sptr output = AllocateOutputBuffer(128, 128, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] gridCnt == 0 +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_003, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 128, + .displayHeight = 128, + .enableGrid = true, + .cols = 0, + .rows = 0, + .tileWidth = 128, + .tileHeight = 128 + }; + decInfo.sampleSize = 1; + sptr output = AllocateOutputBuffer(128, 128, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] gridSize == 0 +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_004, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 128, + .displayHeight = 128, + .enableGrid = true, + .cols = 1, + .rows = 1, + .tileWidth = 0, + .tileHeight = 0 + }; + decInfo.sampleSize = 1; + sptr output = AllocateOutputBuffer(128, 128, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] displaySize > gridSize * gridCnt +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_005, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 512, + .displayHeight = 512, + .enableGrid = true, + .cols = 1, + .rows = 1, + .tileWidth = 256, + .tileHeight = 256 + }; + decInfo.sampleSize = 1; + sptr output = AllocateOutputBuffer(512, 512, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] not enough input (no grid) +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_006, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 512, + .displayHeight = 512, + .enableGrid = false, + .cols = 1, + .rows = 1, + .tileWidth = 512, + .tileHeight = 512 + }; + decInfo.sampleSize = 1; + sptr output = AllocateOutputBuffer(512, 512, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + inputs.push_back(Ashmem::CreateAshmem("", 512 * 512)); + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] not enough input (grid) +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_007, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 512, + .displayHeight = 512, + .enableGrid = true, + .cols = 1, + .rows = 2, + .tileWidth = 512, + .tileHeight = 256 + }; + decInfo.sampleSize = 1; + sptr output = AllocateOutputBuffer(512, 512, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + inputs.push_back(Ashmem::CreateAshmem("", 512 * 512)); + inputs.push_back(Ashmem::CreateAshmem("", 512 * 512)); + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] sampleSize = 1, output is too small +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_008, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 512, + .displayHeight = 512, + .enableGrid = false, + .cols = 1, + .rows = 1, + .tileWidth = 512, + .tileHeight = 512 + }; + decInfo.sampleSize = 1; + sptr output = AllocateOutputBuffer(128, 128, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] unsupported sampleSize +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_009, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 512, + .displayHeight = 512, + .enableGrid = false, + .cols = 1, + .rows = 1, + .tileWidth = 512, + .tileHeight = 512 + }; + decInfo.sampleSize = 3; + sptr output = AllocateOutputBuffer(512, 512, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] displaySize % sampleSize != 0 +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_010, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 511, + .displayHeight = 511, + .enableGrid = false, + .cols = 1, + .rows = 1, + .tileWidth = 512, + .tileHeight = 512 + }; + decInfo.sampleSize = 4; + sptr output = AllocateOutputBuffer(128, 128, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YCBCR_420_SP); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} + +// [fail] unsupported output pixel format +HWTEST_F(CodecHdiHeifDecodeTest, HdfCodecHdiDoHeifDecodeTest_011, TestSize.Level1) +{ + ASSERT_TRUE(hdiHeifDecoder_ != nullptr); + CodecHeifDecInfo decInfo; + decInfo.gridInfo = { + .displayWidth = 512, + .displayHeight = 512, + .enableGrid = false, + .cols = 1, + .rows = 1, + .tileWidth = 512, + .tileHeight = 512 + }; + decInfo.sampleSize = 2; + sptr output = AllocateOutputBuffer(256, 256, + OHOS::HDI::Display::Composer::V1_2::PIXEL_FMT_YUV_422_I); + vector> inputs; + int32_t ret = hdiHeifDecoder_->DoHeifDecode(inputs, output, decInfo); + ASSERT_NE(ret, HDF_SUCCESS); +} +} \ No newline at end of file -- Gitee From d3da514ac020e58b1844cae59767ae3b8b3a5cee Mon Sep 17 00:00:00 2001 From: JillFred Date: Tue, 1 Jul 2025 00:55:29 +0000 Subject: [PATCH 2/2] update codec/test/demo/heif/src/codec_heif_decode_helper.cpp. Signed-off-by: JillFred --- codec/bundle.json | 1 - codec/test/demo/heif/BUILD.gn | 1 - codec/test/demo/heif/src/codec_heif_decode_helper.cpp | 7 +++---- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/codec/bundle.json b/codec/bundle.json index 9e1dfcee9c..c41568437e 100644 --- a/codec/bundle.json +++ b/codec/bundle.json @@ -34,7 +34,6 @@ "hdf_core", "hitrace", "hilog", - "init", "ipc", "openmax" ], diff --git a/codec/test/demo/heif/BUILD.gn b/codec/test/demo/heif/BUILD.gn index fe2a2b110d..962809e7be 100644 --- a/codec/test/demo/heif/BUILD.gn +++ b/codec/test/demo/heif/BUILD.gn @@ -76,7 +76,6 @@ ohos_executable("codec_heif_decode") { "hdf_core:libhdf_utils", "hdf_core:libhdi", "hilog:libhilog", - "init:libbegetutil", "ipc:ipc_single", "graphic_surface:buffer_handle", "graphic_surface:surface", diff --git a/codec/test/demo/heif/src/codec_heif_decode_helper.cpp b/codec/test/demo/heif/src/codec_heif_decode_helper.cpp index 07a083004b..3b450a112b 100644 --- a/codec/test/demo/heif/src/codec_heif_decode_helper.cpp +++ b/codec/test/demo/heif/src/codec_heif_decode_helper.cpp @@ -20,13 +20,14 @@ #include #include #include +#include +#include #include #include #include "surface_buffer.h" #include "v2_0/cm_color_space.h" #include "v2_0/buffer_handle_meta_key_type.h" #include "log.h" -#include "syspara/parameters.h" #include "codec_heif_decode_helper.h" namespace OHOS::VDI::HEIF { @@ -223,9 +224,7 @@ void HeifDecoderHelper::DoDecode() int32_t ret = hdiHeifDecoder->DoHeifDecode(inputs, output, decInfo_); if (ret == HDF_SUCCESS) { cout << "heif decode succeed" << endl; - if (OHOS::system::GetBoolParameter("hdi.image.heif.decode.dump", false)) { - DumpOutput(output); - } + DumpOutput(output); } else { cout << "heif decode failed" << endl; } -- Gitee