diff --git a/OAT.xml b/OAT.xml
index f591c15689c4290b40f19e44855dfb7ea1dedc74..b24cb10361f245fe64cc9c218058c56e04bc82fe 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -1638,6 +1638,23 @@ Note:If the text contains special characters, please escape them according to th
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/UI/DecodeHEIFImage/.gitignore b/code/UI/DecodeHEIFImage/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..08d606210b3993e8f1f4535767bb3459b7b1d208
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/.gitignore
@@ -0,0 +1,13 @@
+/node_modules
+/oh_modules
+/local.properties
+/.idea
+**/build
+/.hvigor
+.cxx
+/.clangd
+/.clang-format
+/.clang-tidy
+**/.test
+/.appanalyzer
+/oh-package-lock.json5
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/AppScope/app.json5 b/code/UI/DecodeHEIFImage/AppScope/app.json5
new file mode 100644
index 0000000000000000000000000000000000000000..675d85d508cf2eb660567801ca5e099b9e25bba4
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/AppScope/app.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+{
+ "app": {
+ "bundleName": "com.samples.decodeheifimage",
+ "vendor": "sample",
+ "versionCode": 1000000,
+ "versionName": "1.0.0",
+ "icon": "$media:app_icon",
+ "label": "$string:app_name"
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/AppScope/resources/base/element/string.json b/code/UI/DecodeHEIFImage/AppScope/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..4cce5d489ce585e025d5abd070208bd8b4dd0feb
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/AppScope/resources/base/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "app_name",
+ "value": "DecodeHEIFImage"
+ }
+ ]
+}
diff --git a/code/UI/DecodeHEIFImage/AppScope/resources/base/media/app_icon.png b/code/UI/DecodeHEIFImage/AppScope/resources/base/media/app_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3
Binary files /dev/null and b/code/UI/DecodeHEIFImage/AppScope/resources/base/media/app_icon.png differ
diff --git a/code/UI/DecodeHEIFImage/README.md b/code/UI/DecodeHEIFImage/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..4a61f64f001ea4ac18996aea23951a1ad22ab218
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/README.md
@@ -0,0 +1,239 @@
+# HEIF软解码器案例
+
+### 介绍
+
+高效图像文件格式HEIF(High Efficiency Image File Format)具有更高的图像质量,更高效的压缩算法,在应用中大量使用,有些应用静态图90%以上都是HEIF图片(.heic后缀)。本示例介绍将[libheif](https://github.com/strukturag/libheif)编译移植到鸿蒙平台,通过网络库[curl](https://curl.se/)请求HEIF图片资源、libheif软解码HEIF图片,最后在瀑布流中加载解码后的HEIF图片的过程。本案例HEIF软解码方案可供开发者调试,硬解码不支持的设备也可以使用软解码方案。
+
+### 效果图预览
+
+
+
+进入本案例首页,开始加载HEIF网络图片的过程:在Taskpool子线程中,通过libcurl网络请求HEIF图片资源,然后通过libheif软解码出HEIF图片数据,调用OH_PixelMap_CreatePixelMap将HEIF图片数据转为PixelMap,主线程获取图片软解码结果后在WaterFlow中加载所有HEIF图片。
+### 实现思路
+
+对于jpg、png和jpeg等系统支持硬解码的图片格式,开发者使用imageSource即可直接解码,创建PixelMap对象后,可以给上层UI组件展示。理论上,对于.heic这类系统暂不支持的图片格式,需要移植自定义解码器(二方库或者三四方库)到鸿蒙平台,然后调用解码器接口解码出原始像素数据,进行字节对齐、颜色变换等操作后,调用NDK的OH_PixelMap_CreatePixelMap函数即可创建PixelMap,给上层UI组件展示。
+
+### 实现方案
+
+#### 1.libheif移植
+
+本文在Linux平台上编译libheif,下载sdk-linux并配置好环境变量,然后按照文档[libheif 集成到应用hap](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/thirdparty/libheif/docs/hap_integrate.md#libheif-%E9%9B%86%E6%88%90%E5%88%B0%E5%BA%94%E7%94%A8hap)的流程进行即可。
+
+**注意事项**
+
+根据[libheif github源工程](https://github.com/strukturag/libheif),libheif解码依赖libde265/ffmpeg,所以还需要集成libd265/ffmpeg。
+
+
+
+libd265移植参考[ libde265 集成到应用hap](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/thirdparty/libde265/docs/hap_integrate.md), libde265文件夹与libheif保持同级目录。
+
+修改thirdparty/libheif/HPKBUILD构建脚本,添加libde265依赖,libde265的编译选项由disable改为enable,这样就可以在libheif编译时链接到libde265。
+
+
+
+
+
+最后编译成功的产物可在/lycium/usr下获取,可以看到thirdparty/libheif/HPKBUILD依赖的库都成功编译了,并且查看libheif.so的属性,运行时会依赖libde265.so。
+
+
+
+
+
+#### 2.使用curl网络请求HEIF图片
+
+本案例将[网络库curl集成到hap](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/thirdparty/curl/docs/hap_integrate.md),这样在Native侧就可以直接请求到HEIF图片,并在Native侧解码,减少跨语言调用开销。
+
+#### 3.读取HEIF图片
+
+libheif允许开发者从不同的来源(磁盘文件、内存、自定义Reader)读取HEIF图片文件,并将其加载到heif_context中,以便后续操作和处理HEIF内容。
+
+本案例以`heif_context_read_from_memory_without_copy`读取网络请求到的HEIF图片(已在内存中)为例。
+
+```c++
+// 创建HEIF上下文指针
+heif_context *ctx = heif_context_alloc();
+
+/**
+功能:从指定的磁盘文件中读取HEIF文件。
+参数:
+struct heif_context*:指向HEIF上下文的指针,用于存储和管理HEIF文件的解码和处理信息。
+const char* filename:指向包含HEIF文件名的字符串的指针。
+const struct heif_reading_options*:指向读取选项的指针。目前应该设置为NULL,表示没有特殊的读取选项。
+*/
+struct heif_error heif_context_read_from_file(struct heif_context*, const char* filename,
+ const struct heif_reading_options*);
+
+/**
+功能:从内存中读取HEIF文件,但提供的内存不会被复制。这意味着,只要使用heif_context,就必须保持内存区域有效。
+参数:
+struct heif_context*:同上。
+const void* mem:指向存储HEIF文件数据的内存块的指针。
+size_t size:内存块的大小,以字节为单位。
+const struct heif_reading_options*:读取选项,同上。
+*/
+struct heif_error heif_context_read_from_memory_without_copy(struct heif_context*,
+ const void* mem, size_t size,
+ const struct heif_reading_options*);
+/**
+功能:从自定义的struct heif_reader(如网络流、加密文件等)中读取HEIF文件。
+参数:
+struct heif_context*:同上。
+const struct heif_reader* reader:指向实现了特定读取函数的heif_reader结构的指针。
+void* userdata:传递给reader回调的用户定义数据。
+const struct heif_reading_options*:读取选项,同上
+*/
+struct heif_error heif_context_read_from_reader(struct heif_context*,
+ const struct heif_reader* reader,
+ void* userdata,
+ const struct heif_reading_options*);
+```
+
+#### 4.解码HEIF图片
+
+解码函数(heif_decode_image)的主要作用是将HEIF图片处理句柄(heif_image_handle)解码为实际的像素图像,并可以设置colorspace和chroma参数来指定输出图像的色彩空间和色度采样方式,如果不需要更改,可以保持为默认值,解码选项参数option可以设置解码后的质量、缩放等。
+
+目前OH_PixelMap_CreatePixelMap颜色编码格式只支持BGRA_8888,但是heif_decode_image不支持该颜色编码格式,所以本案例指定HEIF图片的编码格式为BGRA。
+
+```cpp
+// 获取主图像句柄
+heif_image_handle *handle;
+heif_context_get_primary_image_handle(ctx, &handle);
+// 从句柄中解码图像
+heif_image *heif_img;
+heif_decode_image(handle, &heif_img, heif_colorspace_RGB, heif_chroma_interleaved_RGBA, nullptr);
+```
+
+#### 5.创建PixelMap
+
+##### 访问heif图像
+
+```cpp
+// 获取图像数据
+int stride;
+uint8_t *data = heif_image_get_plane_readonly(heif_img, heif_channel_interleaved, &stride);
+```
+
+>在访问heif图像数据时,需要考虑stride,表示图像中每行像素数据在内存中所占的字节数。通常,图像数据在内存中是连续存储的,但是由于内存对齐等因素,每行的字节数可能会大于实际图像的实际宽度,即stride > width * bpp,width是图片的宽度,bpp(bytes per pixel)是每像素的字节数。
+
+##### 字节对齐
+
+RGBA格式下,如果stride > width * bpp,即每行的字节数可能会大于图像的实际宽度,此时需要字节对齐,参考如下代码。
+
+```c++
+const size_t bpp = 4; // 颜色格式为BGRA,每个像素4个字节
+const size_t pixel_count = width * height; // 像素总数
+const size_t row_bytes = width * bpp; // 每一行的字节数,每个像素4个字节
+const size_t total_size = pixel_count * bpp; // 计算平面的总数据大小
+
+uint8_t *new_data = data; // 默认指向原数据
+bool needAlignment = stride != row_bytes; // 是否需要字节对齐
+if (needAlignment) {
+ new_data = new uint8_t[total_size];
+ // 字节对齐
+ for (int row = 0; row < height; row++) {
+ memcpy(new_data + row * row_bytes, data + row * stride, row_bytes);
+ }
+}
+```
+
+##### 颜色编码格式变换
+
+目前OH_PixelMap_CreatePixelMap颜色编码格式只支持BGRA(API12开始会新增),而HEIF的颜色格式为RGBA,所以需要将RGBA转换为BGRA。
+
+```c++
+// 定义颜色编码格式转换函数
+void swapRBChannels(uint8_t *pixels, int pixelCount) {
+ for (int i = 0; i < pixelCount; i++) {
+ std::swap(pixels[i * 4], pixels[i * 4 + 2]);
+ }
+}
+```
+
+##### 创建PixelMap
+
+定义HEIF的宽高、颜色编码格式,调用NDK的OH_PixelMap_CreatePixelMap函数即可创建PixelMap。
+
+```c++
+struct OhosPixelMapCreateOps createOps;
+createOps.width = width;
+createOps.height = height;
+createOps.pixelFormat = 4; // BGRA
+createOps.alphaType = 0;
+
+int32_t res = OH_PixelMap_CreatePixelMap(env, createOps, (void *)new_data, total_size, &pixel_map);
+if (res != IMAGE_RESULT_SUCCESS || pixel_map == nullptr) {
+ OH_LOG_ERROR(LOG_APP, "创建pixelMap错误");
+ return nullptr;
+}
+```
+
+### 高性能知识点
+
+1. 本示例使用了LazyForEach进行数据懒加载,WaterFlow布局时会根据可视区域按需创建FlowItem组件,并在FlowItem滑出可视区域外时销毁以降低内存占用。
+2. 本案例的图片软解码使用Taskpool来实现多线程并发能力,提升系统资源利用率,减少主线程负载,加快应用的启动速度和响应速度。
+
+### 工程结构&模块类型
+
+```txt
+```
+decodeheifimage // har类型
+|---libs\
+| |---arm64-v8a\libde265.so // arm64-v8a类型libde265库
+| |---arm64-v8a\libheif.so.1 // arm64-v8a类型libheif库
+| |---arm64-v8a\libnativedownloadheif.so // arm64-v8a类型基于libcurl的网络请求so
+| |---arm64-v8a\libnativedecodeheif.so // arm64-v8a类型基于libheif的HEIF解码so
+|---src\main\ets\components\
+| |---ReusableFlowItem.ets // 公共组件-瀑布流FlowItem组件
+|---src\main\ets\model\ // 模型层
+| |---WaterFlowData.ets // 瀑布流数据和操作类
+| |---TaskPool.ets // TaskPool子线程加载so库
+|---src\main\ets\
+| |---DecodeHEIFImageView.ets // 主页面
+|---src\main\cpp\
+| |--- CMakeLists.txt // C++编译和链接配置成
+| |--- decode_heif_image.cpp // 基于libheif的HEIF软解码实现
+| |--- download_heif_image.cpp // 基于libcurl的网络请求实现
+| |--- napi_init.cpp // native层HEIF软解码实现
+```
+```
+
+### 模块依赖
+
+1. 依赖公共libs库中的[libcurl.so](./decodeheifimage/libs/arm64-v8a/libcurl.so),进行Native侧的网络请求HEIF图片资源。
+
+### 参考资料
+
+[高效并发编程](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/performance/efficient-concurrent-programming.md#/openharmony/docs/blob/master/zh-cn/application-dev/arkts-utils/cpu-intensive-task-development.md)
+
+[WaterFlow+LazyForEach详细用法可参考性能范例](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/performance/waterflow_optimization.md)
+
+[libheif github源工程](https://github.com/strukturag/libheif)
+
+[libheif 集成到应用hap](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/thirdparty/libheif/docs/hap_integrate.md#libheif-%E9%9B%86%E6%88%90%E5%88%B0%E5%BA%94%E7%94%A8hap)
+
+[libde265 集成到应用hap](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/thirdparty/libde265/docs/hap_integrate.md)
+
+[网络库curl集成到hap](https://gitee.com/openharmony-sig/tpc_c_cplusplus/blob/master/thirdparty/curl/docs/hap_integrate.md)
+
+### 相关权限
+
+不涉及
+
+### 约束与限制
+
+1.本示例仅支持在标准系统上运行,支持设备:Phone。
+
+2.本示例为Stage模型,支持API12版本SDK,SDK版本号(API Version 12 Release)。
+
+3.本示例需要使用DevEco Studio 5.0.0 Release 才可编译运行。
+
+### 下载
+
+如需单独下载本工程,执行如下命令:
+```javascript
+git init
+git config core.sparsecheckout true
+echo code/UI/DecodeHEIFImage/ > .git/info/sparse-checkout
+git remote add origin https://gitee.com/openharmony/applications_app_samples.git
+git pull origin master
+```
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/build-profile.json5 b/code/UI/DecodeHEIFImage/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..ccf80bde66d9150e6aee8fece6d6aa9af82b8c3b
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/build-profile.json5
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+{
+ "app": {
+ "signingConfigs": [],
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ "compatibleSdkVersion": 12,
+ "compileSdkVersion": 12,
+ "runtimeOS": "OpenHarmony",
+ "buildOption": {
+ "strictMode": {
+ "caseSensitiveCheck": true,
+ "useNormalizedOHMUrl": true
+ }
+ }
+ }
+ ],
+ "buildModeSet": [
+ {
+ "name": "debug",
+ },
+ {
+ "name": "release"
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "decodeheifimage",
+ "srcPath": "./decodeheifimage"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/code-linter.json5 b/code/UI/DecodeHEIFImage/code-linter.json5
new file mode 100644
index 0000000000000000000000000000000000000000..28586467ee7a761c737d8654a73aed6fddbc3c71
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/code-linter.json5
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+{
+ "files": [
+ "**/*.ets"
+ ],
+ "ignore": [
+ "**/src/ohosTest/**/*",
+ "**/src/test/**/*",
+ "**/src/mock/**/*",
+ "**/node_modules/**/*",
+ "**/oh_modules/**/*",
+ "**/build/**/*",
+ "**/.preview/**/*"
+ ],
+ "ruleSet": [
+ "plugin:@performance/recommended",
+ "plugin:@typescript-eslint/recommended"
+ ],
+ "rules": {
+ }
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/.gitignore b/code/UI/DecodeHEIFImage/decodeheifimage/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..eadab4e1522296628f32a70228b2c758ecab4759
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/.gitignore
@@ -0,0 +1,7 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
+/oh-package-lock.json5
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/Index.ets b/code/UI/DecodeHEIFImage/decodeheifimage/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..8b97c5844c9f9a57c09e787b0dd2c165fca5b8dc
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/Index.ets
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+export { DecodeHEIFImageView } from './src/main/ets/DecodeHEIFImageView';
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/build-profile.json5 b/code/UI/DecodeHEIFImage/decodeheifimage/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c1fa46c55738ee34f48d4227b66acdc1d49079ca
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/build-profile.json5
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ "externalNativeOptions": {
+ "path": "./src/main/cpp/CMakeLists.txt",
+ "abiFilters": [
+ "arm64-v8a"
+ ],
+ "arguments": "",
+ "cppFlags": "-s"
+ },
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": true,
+ "files": [
+ "./obfuscation-rules.txt"
+ ]
+ },
+ "consumerFiles": [
+ "./consumer-rules.txt"
+ ]
+ }
+ },
+ "nativeLib": {
+ "debugSymbol": {
+ "strip": true,
+ "exclude": [],
+ },
+ }
+ },
+ ],
+ "targets": [
+ {
+ "name": "default"
+ }
+ ]
+}
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/consumer-rules.txt b/code/UI/DecodeHEIFImage/decodeheifimage/consumer-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/hvigorfile.ts b/code/UI/DecodeHEIFImage/decodeheifimage/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0785a511e1f806573e5208d382645d48719a0f06
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+import { harTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: harTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libcurl.so b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libcurl.so
new file mode 100644
index 0000000000000000000000000000000000000000..a142c9eff002cd215988cd5a47507ead80262fdb
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libcurl.so
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:68513537d89347706a4f55a31a3139be3cdf09e110bb79fb7a1d3ceec8a6200d
+size 1205712
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libde265.so b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libde265.so
new file mode 100644
index 0000000000000000000000000000000000000000..aab6fbaaa0ac32001cec496583992d7f751b5c4d
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libde265.so
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:923151aaafa7700dccdd77543b215306b2e63e5ffef453abe1dc7ad8d176a8d7
+size 911840
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libheif.so.1 b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libheif.so.1
new file mode 100644
index 0000000000000000000000000000000000000000..d18105aba60cb6d2f593983e8da47603689233e3
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libheif.so.1 differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libnativedecodeheif.so b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libnativedecodeheif.so
new file mode 100644
index 0000000000000000000000000000000000000000..700fad26048b8d22d845b1bdde65f5131690b4aa
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libnativedecodeheif.so
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4b1430e08775527e493009496cf4cd6e1618645b2d14ee827890ae8e57236e66
+size 50768
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libnativedownloadheif.so b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libnativedownloadheif.so
new file mode 100644
index 0000000000000000000000000000000000000000..995694fc4151d508b9f6477516dcca25a10e825e
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/libs/arm64-v8a/libnativedownloadheif.so
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3d2ac4e64235fcf5a9715d3fcf4345dd9ef742f24fd77ae4f091eea969756185
+size 49544
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/obfuscation-rules.txt b/code/UI/DecodeHEIFImage/decodeheifimage/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/obfuscation-rules.txt
@@ -0,0 +1,23 @@
+# Define project specific obfuscation rules here.
+# You can include the obfuscation configuration files in the current module's build-profile.json5.
+#
+# For more details, see
+# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
+
+# Obfuscation options:
+# -disable-obfuscation: disable all obfuscations
+# -enable-property-obfuscation: obfuscate the property names
+# -enable-toplevel-obfuscation: obfuscate the names in the global scope
+# -compact: remove unnecessary blank spaces and all line feeds
+# -remove-log: remove all console.* statements
+# -print-namecache: print the name cache that contains the mapping from the old names to new names
+# -apply-namecache: reuse the given cache file
+
+# Keep options:
+# -keep-property-name: specifies property names that you want to keep
+# -keep-global-name: specifies names that you want to keep in the global scope
+
+-enable-property-obfuscation
+-enable-toplevel-obfuscation
+-enable-filename-obfuscation
+-enable-export-obfuscation
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/oh-package.json5 b/code/UI/DecodeHEIFImage/decodeheifimage/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..a026549463d92216294379a3e580843d868cf006
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/oh-package.json5
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+{
+ "name": "decodeheifimage",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "Index.ets",
+ "author": "",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "libdecodeheifimage.so": "file:./src/main/cpp/types/libdecodeheifimage"
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/CMakeLists.txt b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3c2d3e1d7ac6906a353474c1f9d7ae7350f24984
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/CMakeLists.txt
@@ -0,0 +1,50 @@
+# the minimum version of CMake.
+cmake_minimum_required(VERSION 3.4.1)
+
+project(decodeheifimage)
+
+set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
+
+if(DEFINED PACKAGE_FIND_FILE)
+ include(${PACKAGE_FIND_FILE})
+endif()
+
+include_directories(${NATIVERENDER_ROOT_PATH}
+ ${NATIVERENDER_ROOT_PATH}/include)
+
+# TODO:知识点:定义一个变量 BUILD_FLAG_SO
+# TODO:知识点:BUILD_FLAG_SO为0时生成封装基于libcurl的HEIF图片网络请求库libnativedownloadheif.so,将生成好的so文件放入根目录的libs目录下,供native接口调用。
+# TODO:知识点:BUILD_FLAG_SO为1时生成封装基于libheif的HEIF图片软解码库libnativedecodeheif.so,将生成好的so文件放入根目录的libs目录下,供native接口调用。
+# TODO:知识点:BUILD_FLAG_SO为2时,生成一个包含native侧的HEIF图片软解码接口decodeHeifImageFromInternet(该接口调用libnativedownloadheif.so和libnativedecodeheif.so导出的网络请求和软解码接口进行HEIF图片软解码)的库,接口decodeHeifImageFromInternet供ArkTS侧调用。
+set(BUILD_FLAG_SO 2)
+
+if(BUILD_FLAG_SO EQUAL 0)
+ # 生成封装libcurl库的libnativedownloadheif.so
+ add_library(nativedownloadheif SHARED download_heif_image.cpp)
+
+ # 配置动态链接,将libcurl.so加入工程中
+ target_link_libraries(nativedownloadheif PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../../../../libs/${OHOS_ARCH}/libcurl.so)
+ # 将libcurl的头文件加入工程中
+ target_include_directories(nativedownloadheif PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/curl/${OHOS_ARCH}/include)
+ target_include_directories(nativedownloadheif PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
+ # 导入napi、ndk相关库
+ target_link_libraries(nativedownloadheif PUBLIC libace_napi.z.so libhilog_ndk.z.so)
+elseif(BUILD_FLAG_SO EQUAL 1)
+ # 生成封装libheif库的libnativedecodeheif.so
+ add_library(nativedecodeheif SHARED decode_heif_image.cpp)
+ # 配置动态链接,将libheif.so加入工程中
+ target_link_libraries(nativedecodeheif PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libheif/${OHOS_ARCH}/lib/libheif.so)
+ # 将libheif的头文件加入工程中
+ target_include_directories(nativedecodeheif PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/libheif/${OHOS_ARCH}/include)
+ target_include_directories(nativedecodeheif PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
+ # 导入napi、ndk相关库
+ target_link_libraries(nativedecodeheif PUBLIC libace_napi.z.so libhilog_ndk.z.so)
+else()
+ # 生成native侧库,供ArkTS侧调用
+ add_library(decodeheifimage SHARED napi_init.cpp)
+ # 导入引用的库路径
+ target_link_directories(decodeheifimage PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH}/)
+ target_include_directories(decodeheifimage PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
+ # 导入napi、ndk相关库及libnativedownloadheif.so和libnativedecodeheif解码库
+ target_link_libraries(decodeheifimage PUBLIC libace_napi.z.so libhilog_ndk.z.so libpixelmap_ndk.z.so libnativedownloadheif.so libnativedecodeheif.so)
+endif()
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/decode_heif_image.cpp b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/decode_heif_image.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5831743c7c580303504a3310c71254392ad7ca69
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/decode_heif_image.cpp
@@ -0,0 +1,144 @@
+/*
+ * 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 "decode_heif_image.h"
+#include
+#include
+#include "common.h"
+#include
+
+extern "C" {
+#include "libheif/heif.h"
+
+DecodeHEIFImage::DecodeHEIFImage() {} // 构造函数
+DecodeHEIFImage::~DecodeHEIFImage() {} // 析构函数
+
+
+// 定义颜色编码格式转换函数
+void DecodeHEIFImage::swapRBChannels(uint8_t *pixels, int pixelCount) {
+ for (int i = 0; i < pixelCount; i++) {
+ std::swap(pixels[i * 4], pixels[i * 4 + 2]);
+ }
+}
+
+DecodeResult *DecodeHEIFImage::decode_heif_image(MemoryStruct chunk) {
+
+ OH_LOG_INFO(LOG_APP, "开始HEIF解码,chunk size: %{public}d", chunk.size);
+ // 创建 heif_context
+ struct heif_context *ctx = heif_context_alloc();
+ if (!ctx) {
+ OH_LOG_ERROR(LOG_APP, "分配 heif_context 失败");
+ return nullptr;
+ }
+ OH_LOG_INFO(LOG_APP, "开始从内存中读取 HEIC 图像");
+ // 从内存中读取 HEIC 图像
+ heif_error err = heif_context_read_from_memory_without_copy(ctx, chunk.memory, chunk.size, nullptr);
+
+ if (err.code != heif_error_Ok) {
+ OH_LOG_ERROR(LOG_APP, "读取 heif 图片错误: %{public}s", err.message);
+ heif_context_free(ctx);
+ return nullptr;
+ }
+ OH_LOG_INFO(LOG_APP, "开始HEIC 图像句柄");
+
+ // 获取主图像句柄
+ heif_image_handle *handle;
+ err = heif_context_get_primary_image_handle(ctx, &handle);
+
+ if (err.code != heif_error_Ok) {
+ OH_LOG_ERROR(LOG_APP, "获取主图像句柄错误: %{public}s", err.message);
+ heif_image_handle_release(handle);
+ heif_context_free(ctx);
+ return nullptr;
+ }
+ OH_LOG_INFO(LOG_APP, "开始解码HEIC 图像");
+
+ // 从句柄中解码图像
+ heif_image *heif_img;
+ err = heif_decode_image(handle, &heif_img, heif_colorspace_RGB, heif_chroma_interleaved_RGBA, nullptr);
+
+ if (err.code != heif_error_Ok) {
+ OH_LOG_ERROR(LOG_APP, "从句柄中解码图像错误: %{public}s", err.message);
+ heif_image_handle_release(handle);
+ heif_context_free(ctx);
+ return nullptr;
+ }
+
+ // 获取图像尺寸
+ int width, height;
+
+ width = heif_image_get_width(heif_img, heif_channel_interleaved);
+ height = heif_image_get_height(heif_img, heif_channel_interleaved);
+ OH_LOG_INFO(LOG_APP, "HEIC 图像 width: %{public}d height: %{public}d", width, height);
+ // 获取图像数据
+ int stride;
+ OH_LOG_INFO(LOG_APP, "开始解码HEIC 图像data");
+ uint8_t *data = heif_image_get_plane_readonly(heif_img, heif_channel_interleaved, &stride);
+ if (data == nullptr) {
+ OH_LOG_ERROR(LOG_APP, "读取到的图像数据为空");
+ if (heif_img != nullptr) {
+ heif_image_release(heif_img);
+ heif_img = nullptr;
+ }
+ if (handle != nullptr) {
+ heif_image_handle_release(handle);
+ handle = nullptr;
+ }
+ if (ctx != nullptr) {
+ heif_context_free(ctx);
+ ctx = nullptr;
+ }
+ return nullptr;
+ }
+
+
+ if (!data) {
+ OH_LOG_ERROR(LOG_APP, "解码失败或图像数据为空");
+ return nullptr;
+ }
+
+ const size_t bpp = 4;
+ const size_t pixel_count = width * height; // 像素总数
+ const size_t row_bytes = width * bpp; // 每一行的字节数,每个像素4个字节
+ const size_t total_size = pixel_count * bpp; // 计算平面的总数据大小
+
+ uint8_t *new_data = data; // 默认指向原数据
+ bool needAlignment = stride != row_bytes; // 是否需要字节对齐
+ if (needAlignment) {
+ new_data = new (std::nothrow) uint8_t[total_size];
+ if (new_data == nullptr) {
+ OH_LOG_ERROR(LOG_APP, "内存分配失败");
+ return nullptr;
+ }
+ // 字节对齐
+ for (int row = 0; row < height; row++) {
+ memcpy(new_data + row * row_bytes, data + row * stride, row_bytes);
+ }
+ }
+ if (new_data == nullptr) {
+ OH_LOG_ERROR(LOG_APP, "图像数据为空,无法进行通道转换");
+ return nullptr;
+ }
+
+ OH_LOG_INFO(LOG_APP, "开始颜色格式转换");
+ // TODO: 知识点:OH_PixelMap_CreatePixelMap目前颜色编码格式只支持BGRA,需要转换颜色格式(RGBA to BRGA)
+
+ swapRBChannels(new_data, pixel_count);
+
+ DecodeResult *decodeResult = new DecodeResult(new_data, stride, width, height);
+
+ return decodeResult;
+}
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/download_heif_image.cpp b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/download_heif_image.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6800167bb75791b37e9d2aaa652b701806f7122
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/download_heif_image.cpp
@@ -0,0 +1,88 @@
+/*
+ * 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 "download_heif_image.h"
+#ifndef COMMONAPPDEVELOPMENT_DOWNLOAD_HEIF_IMAGE_CPP
+#define COMMONAPPDEVELOPMENT_DOWNLOAD_HEIF_IMAGE_CPP
+
+extern "C" {
+#include "curl.h"
+#include "easy.h"
+/**
+ * 下载HEIF图像(.heic格式网络图片)
+ * @param imageUrl HEIF图像下载链接
+ * @return 下载的HEIF图像数据
+ */
+
+DownloadHEIFImage::DownloadHEIFImage(){}; // 构造函数
+DownloadHEIFImage::~DownloadHEIFImage(){}; // 析构函数
+/**
+ *
+ * @param contents
+ * @param size
+ * @param nmemb
+ * @param userp
+ * @return
+ */
+size_t DownloadHEIFImage::HttpPostWriteBack(void *contents, size_t size, size_t nmemb, void *userp) {
+ size_t realsize = size * nmemb; // 一次回调返回的数据量
+ auto *mem = static_cast(userp);
+
+ char *ptr = (char *)realloc(mem->memory, mem->size + realsize + 1); // 增加1字节用于结束符
+ if (ptr == nullptr) {
+ OH_LOG_ERROR(LOG_APP, "not enough memory (realloc returned NULL)\n");
+ return 0; // 返回0表示错误
+ }
+
+ mem->memory = ptr;
+ memcpy(&(mem->memory[mem->size]), contents, realsize);
+ mem->size += realsize;
+ mem->memory[mem->size] = '\0'; // 确保以空字符结尾
+ return realsize;
+}
+
+MemoryStruct DownloadHEIFImage::get(std::string imageUrl) {
+ CURL *curl = curl_easy_init();
+ // 获取数据
+ MemoryStruct chunk;
+ if (!curl) {
+ OH_LOG_ERROR(LOG_APP, "Failed to initial Image");
+ chunk.size = -1;
+ return chunk;
+ }
+
+ // 支持https
+ curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
+ // 访问网址
+ curl_easy_setopt(curl, CURLOPT_URL, imageUrl.c_str());
+
+ curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &DownloadHEIFImage::HttpPostWriteBack);
+
+ curl_easy_setopt(curl, CURLOPT_WRITEDATA, &chunk);
+
+ // 运行
+ CURLcode res = curl_easy_perform(curl);
+ if (res != CURLE_OK) {
+ OH_LOG_ERROR(LOG_APP, "curl_easy_perform() failed: %{public}s", curl_easy_strerror(res));
+ free(chunk.memory); // 释放内存
+ chunk.memory = nullptr; // 防止悬空指针
+ chunk.size = 0; // 清空大小
+ }
+ curl_easy_cleanup(curl); // 释放句柄
+
+ return chunk;
+}
+#endif
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/common.h b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/common.h
new file mode 100644
index 0000000000000000000000000000000000000000..a7e1295ea2cb402167ebb20816eca4b50a730fdd
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/common.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+#ifndef COMMONAPPDEVELOPMENT_MEMORYSTRUCT_H
+#define COMMONAPPDEVELOPMENT_MEMORYSTRUCT_H
+
+#include "stdint.h"
+#include
+#include
+#include
+struct MemoryStruct {
+ char *memory;
+ size_t size;
+
+ // 构造函数
+ MemoryStruct() : memory(nullptr), size(0) {
+ memory = (char *)malloc(1); // 初始分配1字节
+ if (memory) {
+ memory[0] = '\0'; // 确保字符串以空字符结尾
+ }
+ }
+
+ // 析构函数
+ ~MemoryStruct() {}
+};
+
+struct DecodeResult {
+ uint8_t *data;
+ int heif_image_stride;
+ int heif_image_width;
+ int heif_image_height;
+
+ DecodeResult(uint8_t *data, int stride, int width, int height) {
+ this->data = data;
+ this->heif_image_stride = stride;
+ this->heif_image_width = width;
+ this->heif_image_height = height;
+ }
+
+ ~DecodeResult() {
+ this->data = nullptr;
+ OH_LOG_INFO(LOG_APP, "析构DecodeResult");
+ }
+};
+
+#endif // COMMONAPPDEVELOPMENT_MEMORYSTRUCT_H
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/decode_heif_image.h b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/decode_heif_image.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b3e50ff4b9b4454b273450e5589b504d945ce12
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/decode_heif_image.h
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+#ifndef COMMONAPPDEVELOPMENT_DECODE_HEIF_IMAGE_H
+#define COMMONAPPDEVELOPMENT_DECODE_HEIF_IMAGE_H
+#include "common.h"
+#include
+
+class DecodeHEIFImage {
+public:
+ DecodeHEIFImage(); // 构造函数
+ ~DecodeHEIFImage(); // 析构函数
+
+ DecodeResult *decode_heif_image(MemoryStruct chunk);
+
+private:
+ void swapRBChannels(uint8_t *pixels, int pixelCount);
+};
+
+#endif // COMMONAPPDEVELOPMENT_DECODE_HEIF_IMAGE_H
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/download_heif_image.h b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/download_heif_image.h
new file mode 100644
index 0000000000000000000000000000000000000000..5d0d259dec7a5278e6e1b15b45657171cbd710d5
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/include/download_heif_image.h
@@ -0,0 +1,32 @@
+/*
+ * 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 "common.h"
+#include
+
+#ifndef COMMONAPPDEVELOPMENT_DOWNLOAD_HEIF_IMAGE_H
+#define COMMONAPPDEVELOPMENT_DOWNLOAD_HEIF_IMAGE_H
+
+class DownloadHEIFImage {
+public:
+ DownloadHEIFImage(); // 构造函数
+ ~DownloadHEIFImage(); // 析构函数
+
+ MemoryStruct get(std::string url);
+ static size_t HttpPostWriteBack(void *contents, size_t size, size_t nmemb, void *userp);
+
+private:
+};
+
+#endif // COMMONAPPDEVELOPMENT_DECODE_HEIF_IMAGE_H
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/napi_init.cpp b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/napi_init.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0573b0316a2b50e7244f8667ce3f94c8c7511fa
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/napi_init.cpp
@@ -0,0 +1,127 @@
+/*
+ * 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 "decode_heif_image.h"
+#include "download_heif_image.h"
+#include "napi/native_api.h"
+#include
+#include
+#include
+
+
+/**
+ * 通过libheif软解码HEIF网络图片
+ * @param env
+ * @param info
+ * @return 解码后的HEIF图片数据
+ */
+static napi_value DecodeHeifImageFromInternet(napi_env env, napi_callback_info info) {
+ napi_value pixel_map = nullptr;
+
+ OH_LOG_INFO(LOG_APP, "Beginning DecodeInternetHeifImage!");
+
+ // 解析参数JS -> C++
+ size_t argc = 1;
+ napi_value argv[1] = {nullptr};
+ napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
+
+ size_t filenameSize;
+ char filenameBuffer[512];
+ napi_get_value_string_utf8(env, argv[0], filenameBuffer, sizeof(filenameBuffer), &filenameSize);
+ std::string imageUrl(filenameBuffer, filenameSize);
+ OH_LOG_INFO(LOG_APP, "url: %{public}s", imageUrl.c_str());
+
+ // 获取网络HEIF
+ DownloadHEIFImage downloadHEIFImage;
+ MemoryStruct chunk = downloadHEIFImage.get(imageUrl);
+
+ if (chunk.size == -1) {
+ OH_LOG_ERROR(LOG_APP, "Fail to download!");
+ return nullptr;
+ }
+
+ OH_LOG_INFO(LOG_APP, "DownloadFromInternet sucess!%{public}d", chunk.size);
+
+ DecodeHEIFImage decodeHEIFImage;
+
+ DecodeResult *decodeResult = decodeHEIFImage.decode_heif_image(chunk);
+
+ OH_LOG_INFO(LOG_APP, "DecodeHEIFImage sucess!%{public}d", decodeResult->heif_image_height);
+
+ const size_t bpp = 4;
+ const size_t pixel_count = decodeResult->heif_image_width * decodeResult->heif_image_height; // 像素总数
+ const size_t row_bytes = decodeResult->heif_image_width * bpp; // 每一行的字节数,每个像素4个字节
+ const size_t total_size = pixel_count * bpp; // 计算平面的总数据大小
+
+ bool needAlignment = decodeResult->heif_image_stride != row_bytes; // 是否需要字节对齐
+ struct OhosPixelMapCreateOps createOps;
+ createOps.width = decodeResult->heif_image_width;
+ createOps.height = decodeResult->heif_image_height;
+ createOps.pixelFormat = 4; // 目前颜色编码格式只支持BGRA
+ createOps.alphaType = 0;
+
+ // TODO: 知识点:调用NDK接口OH_PixelMap_CreatePixelMap创建PixelMap
+ int32_t res = OH_PixelMap_CreatePixelMap(env, createOps, (void *)decodeResult->data, total_size, &pixel_map);
+ if (res != IMAGE_RESULT_SUCCESS || pixel_map == nullptr) {
+ OH_LOG_ERROR(LOG_APP, "创建pixelMap错误");
+ return nullptr;
+ }
+
+ const char *keys[] = {"data", "width", "height"};
+ napi_value values[3];
+ values[0] = pixel_map;
+ napi_create_int32(env, decodeResult->heif_image_width, &values[1]);
+ napi_create_int32(env, decodeResult->heif_image_height, &values[2]);
+
+ napi_value result;
+ napi_create_object_with_named_properties(env, &result, 3, keys, values);
+
+ OH_LOG_INFO(LOG_APP, "napi_create_object_with_named_properties success");
+ // 清理资源
+ if (needAlignment && decodeResult->data != nullptr) {
+ delete[] decodeResult->data;
+ }
+
+ // 释放chunk
+ if (chunk.memory) {
+ OH_LOG_INFO(LOG_APP, "释放chunk");
+ free(chunk.memory);
+ chunk.memory = nullptr;
+ chunk.size = 0;
+ }
+
+ return result;
+}
+
+EXTERN_C_START
+static napi_value Init(napi_env env, napi_value exports) {
+ napi_property_descriptor desc[] = {{"decodeHeifImageFromInternet", nullptr, DecodeHeifImageFromInternet, nullptr,
+ nullptr, nullptr, napi_default, nullptr}};
+ napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
+ return exports;
+}
+EXTERN_C_END
+
+static napi_module demoModule = {
+ .nm_version = 1,
+ .nm_flags = 0,
+ .nm_filename = nullptr,
+ .nm_register_func = Init,
+ .nm_modname = "decodeheifimage",
+ .nm_priv = ((void *)0),
+ .reserved = {0},
+};
+
+extern "C" __attribute__((constructor)) void RegisterDecodeHEIFImageModule(void) { napi_module_register(&demoModule); }
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/types/libdecodeheifimage/index.d.ts b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/types/libdecodeheifimage/index.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2ba930f3560c76dc57f0d87ac955424d317f1e85
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/types/libdecodeheifimage/index.d.ts
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+import { image } from '@kit.ImageKit';
+export interface IHEIFInfo {
+ data: image.PixelMap;
+ width: number;
+ height: number;
+}
+export const decodeHeifImageFromInternet: (url: string) => IHEIFInfo;
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/types/libdecodeheifimage/oh-package.json5 b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/types/libdecodeheifimage/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..696706aeb464da88dc41be0ebacaca04b69089e8
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/cpp/types/libdecodeheifimage/oh-package.json5
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+{
+ "name": "libdecodeheifimage.so",
+ "types": "./index.d.ts",
+ "version": "",
+ "description": "Please describe the basic information."
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/DecodeHEIFImageView.ets b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/DecodeHEIFImageView.ets
new file mode 100644
index 0000000000000000000000000000000000000000..60989c73f86da9c8e55f6d6bcac223d90c30df2b
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/DecodeHEIFImageView.ets
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+/**
+ * 实现步骤:
+ * 1. 集成三方库libheif及其依赖库libde265来实现软解码,集成网络库curl,这样在Native侧就可以直接请求到HEIF图片,并在Native侧解码,减少跨语言调用开销
+ * 2. 网络请求和HEIF图片软解码使用Taskpool来实现多线程并发能力
+ * 3. 在HEIF软解码过程中
+ * 3.1 通过heif_context_read_from_memory_without_copy读取网络请求到的HEIF资源(已存在内存中)
+ * 3.2 调用解码接口heif_decode_image解码HEIF图片
+ * 3.3 调用heif_image_get_plane_readonly获取HEIF图片数据data
+ * 3.4 字节对齐和颜色编码格式转换
+ * 3.5 定义HEIF的宽高、颜色编码格式,调用NDK的OH_PixelMap_CreatePixelMap函数即可创建PixelMap
+ * 4. WaterFlow + LazyForEach加载解码后的HEIF图片数据
+ */
+
+import { heifUrls, ImageInfo, WaterFlowDataSource } from './model/WaterFlowData';
+import { ReusableFlowItem } from './components/ReusableFlowItem';
+import { executeTasks } from './model/Taskpool';
+
+
+@Component
+export struct DecodeHEIFImageView {
+ private dataSource: WaterFlowDataSource = new WaterFlowDataSource();
+
+ aboutToAppear(): void {
+ // TODO:知识点:在Taskpool中执行异步并发任务(网络请求和图片软解码)
+ executeTasks(heifUrls, this.dataSource);
+ }
+
+ build() {
+ Column() {
+ WaterFlow() {
+ // TODO: 知识点: LazyForEach提供列表数据按需加载能力,解决一次性加载长列表数据耗时长、占用过多资源的问题,可以提升页面响应速度
+ LazyForEach(this.dataSource, (item: ImageInfo) => {
+ FlowItem() {
+ ReusableFlowItem({ item })
+ }
+ .width('100%')
+ .margin({
+ top: $r("app.integer.decode_heif_image_flow_item_margin_top"),
+ bottom: $r("app.integer.decode_heif_image_flow_item_margin_bottom")
+ })
+ }, (item: ImageInfo, index: number) => index + JSON.stringify(item))
+ }
+ .cachedCount(1) // 当前案例数据量少设置为1,如果数据量较多可适当调整
+ .columnsTemplate('1fr 1fr')
+ .columnsGap($r("app.integer.decode_heif_image_water_flow_column_gap"))
+ }
+ .width('100%')
+ .height('100%')
+ .padding($r("app.integer.decode_heif_image_padding"))
+ .backgroundColor($r("app.color.decode_heif_image_background_color"))
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/components/ReusableFlowItem.ets b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/components/ReusableFlowItem.ets
new file mode 100644
index 0000000000000000000000000000000000000000..734597245d756add24f6d576b75b81c40f856b8d
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/components/ReusableFlowItem.ets
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ */
+
+import { ImageInfo } from '../model/WaterFlowData';
+
+@Reusable
+@Component
+export struct ReusableFlowItem {
+ @State item: ImageInfo | null = null;
+
+ // TODO:知识点:从复用缓存中加入到组件树之前调用,可在此处更新组件的状态变量以展示正确的内容
+ aboutToReuse(params: ESObject) {
+ this.item = params.item;
+ }
+
+ build() {
+ Column() {
+ Image(this.item?.data)
+ .objectFit(ImageFit.Contain)
+ .width('100%')
+ .borderRadius({
+ topLeft: $r("app.integer.decode_heif_image_flow_item_image_border_radius_top_left"),
+ topRight: $r("app.integer.decode_heif_image_flow_item_image_border_radius_top_right")
+ })
+
+ Text(this.item?.description)
+ .fontSize($r("app.integer.decode_heif_image_flow_item_text_font_size"))
+ .fontColor($r("app.color.decode_heif_image_flow_item_font_color"))
+ .margin({
+ top: $r("app.integer.decode_heif_image_flow_item_text_margin_top"),
+ bottom: $r("app.integer.decode_heif_image_flow_item_text_margin_bottom")
+ })
+ }
+ .width('100%')
+ .shadow(ShadowStyle.OUTER_DEFAULT_XS)
+ .borderRadius($r("app.integer.decode_heif_image_flow_item_border_radius"))
+ .backgroundColor(Color.White)
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/model/Taskpool.ets b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/model/Taskpool.ets
new file mode 100644
index 0000000000000000000000000000000000000000..29c9bf738361d031fe67704728897833949ce95e
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/model/Taskpool.ets
@@ -0,0 +1,58 @@
+/*
+ * 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.
+ */
+
+import { taskpool } from '@kit.ArkTS';
+import testNapi, { IHEIFInfo } from 'libdecodeheifimage.so';
+import { WaterFlowDataSource, ImageInfo } from './WaterFlowData';
+
+@Concurrent
+export function decodeHeifImage(url: string): IHEIFInfo {
+ const result = testNapi.decodeHeifImageFromInternet(url);
+ return result;
+}
+
+/**
+ * 获取taskpool异步任务列表
+ * @param urls 图片资源链接数组
+ * @returns taskpool.Task[]
+ */
+export function getTasks(urls: string[]): taskpool.Task[] {
+ const tasks: taskpool.Task[] = [];
+ for (let i = 0; i < urls.length; i++) {
+ tasks.push(new taskpool.Task(decodeHeifImage, urls[i]));
+ }
+ return tasks;
+}
+
+/**
+ * 执行taskpool异步任务列表中的每一个任务
+ * @param urls 图片资源链接数组
+ * @param dataSource 瀑布流数据操作实例
+ */
+export function executeTasks(urls: string[], dataSource: WaterFlowDataSource) {
+ const tasks = getTasks(urls);
+ for (let i = 0; i < tasks.length; i++) {
+ taskpool.execute(tasks[i], taskpool.Priority.HIGH)
+ .then(result => {
+ const imageInfo = result as ImageInfo;
+ if (result !== null) {
+ dataSource.addData(i, new ImageInfo(imageInfo.data, imageInfo.width, imageInfo.height, `image${i + 1}.heic`));
+ }
+ })
+ .catch((err: Error) => {
+ console.error(JSON.stringify(err))
+ })
+ }
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/model/WaterFlowData.ets b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/model/WaterFlowData.ets
new file mode 100644
index 0000000000000000000000000000000000000000..fcf65368efe89757a883871a43a78cf2c847e667
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/ets/model/WaterFlowData.ets
@@ -0,0 +1,127 @@
+/*
+ * 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.
+ */
+
+import { image } from '@kit.ImageKit';
+
+/**
+ * 图片信息类
+ */
+export class ImageInfo {
+ data: image.PixelMap | null = null;
+ width: number = 0;
+ height: number = 0;
+ description: string | undefined = undefined;
+
+ constructor(data: image.PixelMap | null, width: number, height: number, description?: string) {
+ this.data = data;
+ this.width = width;
+ this.height = height;
+ this.description = description;
+ }
+}
+
+// HEIF图片资源链接
+export const heifUrls: string[] = [
+ "https://gitee.com/harmonyos-cases/cases/raw/master/CommonAppDevelopment/feature/decodeheifimage/src/main/resources/base/media/image1.heic",
+ "https://gitee.com/harmonyos-cases/cases/raw/master/CommonAppDevelopment/feature/decodeheifimage/src/main/resources/base/media/image2.heic",
+ "https://gitee.com/harmonyos-cases/cases/raw/master/CommonAppDevelopment/feature/decodeheifimage/src/main/resources/base/media/image3.heic",
+ "https://gitee.com/harmonyos-cases/cases/raw/master/CommonAppDevelopment/feature/decodeheifimage/src/main/resources/base/media/image4.heic",
+ "https://gitee.com/harmonyos-cases/cases/raw/master/CommonAppDevelopment/feature/decodeheifimage/src/main/resources/base/media/image5.heic",
+ "https://gitee.com/harmonyos-cases/cases/raw/master/CommonAppDevelopment/feature/decodeheifimage/src/main/resources/base/media/image6.heic",
+];
+
+/**
+ * 实现IDataSource接口的对象,用于瀑布流组件加载数据
+ */
+export class WaterFlowDataSource implements IDataSource {
+ private dataArray: ImageInfo[] = [];
+ private listeners: DataChangeListener[] = [];
+
+ public totalCount(): number {
+ return this.dataArray.length;
+ }
+
+ public getData(index: number): ImageInfo {
+ return this.dataArray[index];
+ }
+
+ public addData(index: number, data: ImageInfo): void {
+ this.dataArray.splice(index, 0, data);
+ this.notifyDataAdd(index);
+ }
+
+ public clearData(): void {
+ this.dataArray = [];
+ this.notifyDataReload();
+ }
+
+ public pushData(data: ImageInfo): void {
+ this.dataArray.push(data);
+ this.notifyDataAdd(this.dataArray.length - 1);
+ }
+
+ // 该方法为框架侧调用,为LazyForEach组件向其数据源处添加listener监听
+ registerDataChangeListener(listener: DataChangeListener): void {
+ if (this.listeners.indexOf(listener) < 0) {
+ console.info('add listener');
+ this.listeners.push(listener);
+ }
+ }
+
+ // 该方法为框架侧调用,为对应的LazyForEach组件在数据源处去除listener监听
+ unregisterDataChangeListener(listener: DataChangeListener): void {
+ const pos = this.listeners.indexOf(listener);
+ if (pos >= 0) {
+ console.info('remove listener');
+ this.listeners.splice(pos, 1);
+ }
+ }
+
+ // 通知LazyForEach组件需要重载所有子组件
+ notifyDataReload(): void {
+ this.listeners.forEach(listener => {
+ listener.onDataReloaded();
+ })
+ }
+
+ // 通知LazyForEach组件需要在index对应索引处添加子组件
+ notifyDataAdd(index: number): void {
+ this.listeners.forEach(listener => {
+ listener.onDataAdd(index);
+ })
+ }
+
+ // 通知LazyForEach组件在index对应索引处数据有变化,需要重建该子组件
+ notifyDataChange(index: number): void {
+ this.listeners.forEach(listener => {
+ listener.onDataChange(index);
+ })
+ }
+
+ // 通知LazyForEach组件需要在index对应索引处删除该子组件
+ notifyDataDelete(index: number): void {
+ this.listeners.forEach(listener => {
+ listener.onDataDelete(index);
+ })
+ }
+
+ // 通知LazyForEach组件将from索引和to索引处的子组件进行交换
+ notifyDataMove(from: number, to: number): void {
+ this.listeners.forEach(listener => {
+ listener.onDataMove(from, to);
+ })
+ }
+}
+
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/module.json5 b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..7c96c8908558fbf4b4f2c1bd5526215f7b2dd0d0
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/module.json5
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+{
+ "module": {
+ "name": "decodeheifimage",
+ "type": "har",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "requestPermissions": [
+ {
+ "name": "ohos.permission.INTERNET"
+ }
+ ]
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/color.json b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..aa1659e8030f1d34842e69003a4c4b0f605f7e26
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/color.json
@@ -0,0 +1,12 @@
+{
+ "color": [
+ {
+ "name": "decode_heif_image_background_color",
+ "value": "#FFDBD9D9"
+ },
+ {
+ "name": "decode_heif_image_flow_item_font_color",
+ "value": "#202020"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/integer.json b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/integer.json
new file mode 100644
index 0000000000000000000000000000000000000000..fecd347ff19eff21465975406a89aa16b0a6e22e
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/integer.json
@@ -0,0 +1,60 @@
+{
+ "integer": [
+ {
+ "name": "decode_heif_image_button_width",
+ "value": 100
+ },
+ {
+ "name": "decode_heif_image_button_margin_top",
+ "value": 10
+ },
+ {
+ "name": "decode_heif_image_button_margin_bottom",
+ "value": 10
+ },
+ {
+ "name": "decode_heif_image_flow_item_margin_top",
+ "value": 5
+ },
+ {
+ "name": "decode_heif_image_flow_item_margin_bottom",
+ "value": 5
+ },
+ {
+ "name": "decode_heif_image_water_flow_cache_count",
+ "value": 5
+ },
+ {
+ "name": "decode_heif_image_water_flow_column_gap",
+ "value": 10
+ },
+ {
+ "name": "decode_heif_image_padding",
+ "value": 5
+ },
+ {
+ "name": "decode_heif_image_flow_item_image_border_radius_top_left",
+ "value": 6
+ },
+ {
+ "name": "decode_heif_image_flow_item_image_border_radius_top_right",
+ "value": 6
+ },
+ {
+ "name": "decode_heif_image_flow_item_border_radius",
+ "value": 6
+ },
+ {
+ "name": "decode_heif_image_flow_item_text_margin_top",
+ "value": 5
+ },
+ {
+ "name": "decode_heif_image_flow_item_text_margin_bottom",
+ "value": 5
+ },
+ {
+ "name": "decode_heif_image_flow_item_text_font_size",
+ "value": 16
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/string.json b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..94e7f29774bdd361a7b67736d7f10fcb0b005127
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "decode_heif_image_title",
+ "value": "HEIF图片软解码"
+ },
+ {
+ "name": "decode_heif_image_button_label",
+ "value": "展示HEIF网络图片"
+ }
+ ]
+}
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/HPKBUILD1.png b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/HPKBUILD1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce7c9e7ce912af1494710e8105326acda11a53dd
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/HPKBUILD1.png differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/HPKBUILD2.png b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/HPKBUILD2.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcd063d13ec3a38c4ba9b998ed9e76c58e74c9ef
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/HPKBUILD2.png differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/decode_heif_image.gif b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/decode_heif_image.gif
new file mode 100644
index 0000000000000000000000000000000000000000..46d5cabbf0d8050bbb726c07b9fa41ee59865ff4
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/decode_heif_image.gif differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image1.heic b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image1.heic
new file mode 100644
index 0000000000000000000000000000000000000000..fcf75f07aa850fcf04fe2de71952b2751c1d63d2
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image1.heic differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image2.heic b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image2.heic
new file mode 100644
index 0000000000000000000000000000000000000000..eafd46c1a0dce545e18809231a8ebd54b88475be
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image2.heic differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image3.heic b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image3.heic
new file mode 100644
index 0000000000000000000000000000000000000000..b55bf44782801aed589d3fc19bb041ce0ec20886
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image3.heic differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image4.heic b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image4.heic
new file mode 100644
index 0000000000000000000000000000000000000000..4693e52b72fc84abf4a950c76f8d9c5fa5a6beb2
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image4.heic differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image5.heic b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image5.heic
new file mode 100644
index 0000000000000000000000000000000000000000..887c1ed7b5d9ad41a1aded9a9236d33c496cf79d
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image5.heic differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image6.heic b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image6.heic
new file mode 100644
index 0000000000000000000000000000000000000000..005df163523a13a65f593b693db20d9fb872f155
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/image6.heic differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_compile_result.png b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_compile_result.png
new file mode 100644
index 0000000000000000000000000000000000000000..fbd446dba2c46279b63d46cbe060cf1c8cb3aed5
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_compile_result.png differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_dependency_so.png b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_dependency_so.png
new file mode 100644
index 0000000000000000000000000000000000000000..9299e12649be8faecced38b2a1cb646eb945e048
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_dependency_so.png differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_symbol_info.png b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_symbol_info.png
new file mode 100644
index 0000000000000000000000000000000000000000..df7c4d16439d4c77ad94a6dec99e4e4a2ff1c0c7
Binary files /dev/null and b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/base/media/libheif_symbol_info.png differ
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/rawfile/routerMap/decodeheifimage.json b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/rawfile/routerMap/decodeheifimage.json
new file mode 100644
index 0000000000000000000000000000000000000000..42e16ca5bb26a6dc962fd62e00eb144bff71c203
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/rawfile/routerMap/decodeheifimage.json
@@ -0,0 +1,10 @@
+{
+ "routerMap": [
+ {
+ "name": "decodeheifimage/DecodeHEIFImageView",
+ "pageModule": "decodeheifimage",
+ "pageSourceFile": "src/main/ets/generated/RouterBuilder.ets",
+ "registerFunction": "decodeHEIFImageViewRegister"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/zh_CN/element/string.json b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..f51a9c8461a55f6312ef950344e3145b7f82d607
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/decodeheifimage/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,8 @@
+{
+ "string": [
+ {
+ "name": "page_show",
+ "value": "page from package"
+ }
+ ]
+}
diff --git a/code/UI/DecodeHEIFImage/entry/.gitignore b/code/UI/DecodeHEIFImage/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..eadab4e1522296628f32a70228b2c758ecab4759
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/.gitignore
@@ -0,0 +1,7 @@
+/node_modules
+/oh_modules
+/.preview
+/build
+/.cxx
+/.test
+/oh-package-lock.json5
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/build-profile.json5 b/code/UI/DecodeHEIFImage/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e7569e3056e27af38e9991b7ea73ec10f3ba8a05
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/build-profile.json5
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+
+{
+ "apiType": "stageMode",
+ "buildOption": {
+ },
+ "buildOptionSet": [
+ {
+ "name": "release",
+ "arkOptions": {
+ "obfuscation": {
+ "ruleOptions": {
+ "enable": false,
+ "files": [
+ "./obfuscation-rules.txt"
+ ]
+ }
+ }
+ }
+ },
+ ],
+ "targets": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/hvigorfile.ts b/code/UI/DecodeHEIFImage/entry/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e4f43d54667f8327c367c8096bd08bb8c75aff54
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+import { hapTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/UI/DecodeHEIFImage/entry/obfuscation-rules.txt b/code/UI/DecodeHEIFImage/entry/obfuscation-rules.txt
new file mode 100644
index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/obfuscation-rules.txt
@@ -0,0 +1,23 @@
+# Define project specific obfuscation rules here.
+# You can include the obfuscation configuration files in the current module's build-profile.json5.
+#
+# For more details, see
+# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5
+
+# Obfuscation options:
+# -disable-obfuscation: disable all obfuscations
+# -enable-property-obfuscation: obfuscate the property names
+# -enable-toplevel-obfuscation: obfuscate the names in the global scope
+# -compact: remove unnecessary blank spaces and all line feeds
+# -remove-log: remove all console.* statements
+# -print-namecache: print the name cache that contains the mapping from the old names to new names
+# -apply-namecache: reuse the given cache file
+
+# Keep options:
+# -keep-property-name: specifies property names that you want to keep
+# -keep-global-name: specifies names that you want to keep in the global scope
+
+-enable-property-obfuscation
+-enable-toplevel-obfuscation
+-enable-filename-obfuscation
+-enable-export-obfuscation
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/oh-package.json5 b/code/UI/DecodeHEIFImage/entry/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..aed9e7f4d342eff3d0f4d4a9305442cd815cc0f8
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/oh-package.json5
@@ -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 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.
+ */
+
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "description": "Please describe the basic information.",
+ "main": "",
+ "author": "",
+ "license": "",
+ "dependencies": {
+ "decodeheifimage": "file:../decodeheifimage"
+ }
+}
+
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/ets/entryability/EntryAbility.ets b/code/UI/DecodeHEIFImage/entry/src/main/ets/entryability/EntryAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..edc2839f203ba057c186e19b0cbbbf80c8faa8b3
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/ets/entryability/EntryAbility.ets
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit';
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { window } from '@kit.ArkUI';
+
+export default class EntryAbility extends UIAbility {
+ onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
+ this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET);
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
+ }
+
+ onDestroy(): void {
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
+ }
+
+ onWindowStageCreate(windowStage: window.WindowStage): void {
+ // Main window is created, set main page for this ability
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
+
+ windowStage.loadContent('pages/Index', (err) => {
+ if (err.code) {
+ hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
+ return;
+ }
+ hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.');
+ });
+ }
+
+ onWindowStageDestroy(): void {
+ // Main window is destroyed, release UI related resources
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
+ }
+
+ onForeground(): void {
+ // Ability has brought to foreground
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
+ }
+
+ onBackground(): void {
+ // Ability has back to background
+ hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
+ }
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/code/UI/DecodeHEIFImage/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..b1e212947256c5533c7b06285a597c94f840a6e3
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets
@@ -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 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 { hilog } from '@kit.PerformanceAnalysisKit';
+import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit';
+
+export default class EntryBackupAbility extends BackupExtensionAbility {
+ async onBackup() {
+ hilog.info(0x0000, 'testTag', 'onBackup ok');
+ }
+
+ async onRestore(bundleVersion: BundleVersion) {
+ hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion));
+ }
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/ets/pages/Index.ets b/code/UI/DecodeHEIFImage/entry/src/main/ets/pages/Index.ets
new file mode 100644
index 0000000000000000000000000000000000000000..e7b290bc6276135c3b49218069c19d84647a2420
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/ets/pages/Index.ets
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+import { DecodeHEIFImageView } from "decodeheifimage";
+
+@Entry
+@Component
+struct Index {
+
+ build() {
+ Column() {
+ DecodeHEIFImageView()
+ }
+ .height('100%')
+ .width('100%')
+ }
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/module.json5 b/code/UI/DecodeHEIFImage/entry/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..4144486d1af4c03b0d767cce1cda86fc0d697f91
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/module.json5
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+
+{
+ "module": {
+ "name": "entry",
+ "type": "entry",
+ "description": "$string:module_desc",
+ "mainElement": "EntryAbility",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false,
+ "pages": "$profile:main_pages",
+ "abilities": [
+ {
+ "name": "EntryAbility",
+ "srcEntry": "./ets/entryability/EntryAbility.ets",
+ "description": "$string:EntryAbility_desc",
+ "icon": "$media:layered_image",
+ "label": "$string:EntryAbility_label",
+ "startWindowIcon": "$media:startIcon",
+ "startWindowBackground": "$color:start_window_background",
+ "exported": true,
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ]
+ }
+ ],
+ "extensionAbilities": [
+ {
+ "name": "EntryBackupAbility",
+ "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets",
+ "type": "backup",
+ "exported": false,
+ "metadata": [
+ {
+ "name": "ohos.extension.backup",
+ "resource": "$profile:backup_config"
+ }
+ ]
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/element/color.json b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/element/string.json b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..1f484705f420ddf722e11d17ab5c5d94ac256061
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "EntryAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "EntryAbility_label",
+ "value": "decodeheifimage"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/background.png b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/background.png differ
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/foreground.png b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/foreground.png differ
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/layered_image.json b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/layered_image.json
new file mode 100644
index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/layered_image.json
@@ -0,0 +1,7 @@
+{
+ "layered-image":
+ {
+ "background" : "$media:background",
+ "foreground" : "$media:foreground"
+ }
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/startIcon.png b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/profile/backup_config.json b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/profile/backup_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/profile/backup_config.json
@@ -0,0 +1,3 @@
+{
+ "allowToBackupRestore": true
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/base/profile/main_pages.json b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/code/UI/DecodeHEIFImage/entry/src/main/resources/dark/element/color.json b/code/UI/DecodeHEIFImage/entry/src/main/resources/dark/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/main/resources/dark/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#000000"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/ohosTest/ets/test/Ability.test.ets b/code/UI/DecodeHEIFImage/entry/src/ohosTest/ets/test/Ability.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0f8ce9a2c012f8fe36114cef65216ef0b6254f41
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/ohosTest/ets/test/Ability.test.ets
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+import { hilog } from '@kit.PerformanceAnalysisKit';
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
+
+export default function abilityTest() {
+ describe('ActsAbilityTest', () => {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(() => {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ })
+ beforeEach(() => {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ })
+ afterEach(() => {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ })
+ afterAll(() => {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ })
+ it('assertContain', 0, () => {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
+ let a = 'abc';
+ let b = 'b';
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b);
+ expect(a).assertEqual(a);
+ })
+ })
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/ohosTest/ets/test/List.test.ets b/code/UI/DecodeHEIFImage/entry/src/ohosTest/ets/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/ohosTest/ets/test/List.test.ets
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+import abilityTest from './Ability.test';
+
+export default function testsuite() {
+ abilityTest();
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/ohosTest/module.json5 b/code/UI/DecodeHEIFImage/entry/src/ohosTest/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..c3fd9dda3040d888d9d8b0b62bcb5d3b6fbeb614
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/ohosTest/module.json5
@@ -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 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.
+ */
+
+{
+ "module": {
+ "name": "entry_test",
+ "type": "feature",
+ "deviceTypes": [
+ "default",
+ "tablet"
+ ],
+ "deliveryWithInstall": true,
+ "installationFree": false
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/entry/src/test/List.test.ets b/code/UI/DecodeHEIFImage/entry/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f1186b1f53c3a70930921c5dbd1417332bec56c9
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/test/List.test.ets
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+import localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest();
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/entry/src/test/LocalUnit.test.ets b/code/UI/DecodeHEIFImage/entry/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..7fc57c77dbf76d8df08a2b802a55b948e3fcf968
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/entry/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
+
+export default function localUnitTest() {
+ describe('localUnitTest', () => {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(() => {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ });
+ beforeEach(() => {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ });
+ afterEach(() => {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ });
+ afterAll(() => {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ });
+ it('assertContain', 0, () => {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ let a = 'abc';
+ let b = 'b';
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b);
+ expect(a).assertEqual(a);
+ });
+ });
+}
\ No newline at end of file
diff --git a/code/UI/DecodeHEIFImage/hvigor/hvigor-config.json5 b/code/UI/DecodeHEIFImage/hvigor/hvigor-config.json5
new file mode 100644
index 0000000000000000000000000000000000000000..d584c19c247db9a7caee4b606bb931aa9279c637
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/hvigor/hvigor-config.json5
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+{
+ "modelVersion": "5.0.1",
+ "dependencies": {
+ },
+ "execution": {
+ // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */
+ // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */
+ // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */
+ // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */
+ // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */
+ },
+ "logging": {
+ // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
+ },
+ "debugging": {
+ // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */
+ },
+ "nodeOptions": {
+ // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/
+ // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/hvigorfile.ts b/code/UI/DecodeHEIFImage/hvigorfile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..2a5e543f190732c159beb574dfc9fa37bc94e156
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/hvigorfile.ts
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+import { appTasks } from '@ohos/hvigor-ohos-plugin';
+
+export default {
+ system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
+ plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
+}
diff --git a/code/UI/DecodeHEIFImage/oh-package.json5 b/code/UI/DecodeHEIFImage/oh-package.json5
new file mode 100644
index 0000000000000000000000000000000000000000..e41bae026aab3b50d0abb42fece08ba43b4a772b
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/oh-package.json5
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+{
+ "modelVersion": "5.0.1",
+ "description": "Please describe the basic information.",
+ "dependencies": {
+ },
+ "devDependencies": {
+ "@ohos/hypium": "1.0.19",
+ "@ohos/hamock": "1.0.0"
+ }
+}
diff --git a/code/UI/DecodeHEIFImage/ohosTest.md b/code/UI/DecodeHEIFImage/ohosTest.md
new file mode 100644
index 0000000000000000000000000000000000000000..952e44324d0546a05eb7950b502249fdf4207ef7
--- /dev/null
+++ b/code/UI/DecodeHEIFImage/ohosTest.md
@@ -0,0 +1,7 @@
+# HEIF软解码器案例测试用例
+
+## 用例表
+
+| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 |
+|----------------|---------------------------|---------------|-------------------------------------|------|------|
+| 正常加载所有HEIF网络图片 | 启动【HEIF软解码器案例】 | 访问【HEIF软解码器案例】 | 进入会出现【HEIF软解码器案例】页面,正常加载所有HEIF网络图片。 | 否 | Pass |
\ No newline at end of file