diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..b4530be306618bfda67fd77473d95109c872bfbe
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,113 @@
+# Copyright (C) 2021 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("//build/config/ohos/rules.gni")
+import("//build/ohos.gni")
+
+#ohos_combine_jars("image_combine_java") {
+ # image
+# deps = [
+# "adapter/frameworks/bitmapconverter/java:imagesystemadapter_java",
+# "adapter/frameworks/exif:image_exifadapter_java",
+# "interfaces/kits/java:image_java",
+# "interfaces/kits/java:image_receiver_java",
+# ]
+
+# if (is_double_framework && !mrt) {
+# dex_path = "${target_out_dir}/image.z.jar"
+# }
+
+# subsystem_name = "multimedia"
+# part_name = "multimedia_image"
+#}
+
+#ohos_maple_java("image_combine_maple_java") {
+# deps = [ ":image_combine_java" ]
+
+# if (is_double_framework) {
+# aosp_deps = [ "maple:framework" ]
+# }
+
+# external_deps = [
+# "ability:abilitykit_java_maple",
+# "ans:intentagent_base_java_maple",
+# "appexecfwk:abilityshell_java_maple",
+# "appexecfwk:appexecfwk_base_java_maple",
+# "appexecfwk:appexecfwk_java_maple",
+# "appexecfwk:eventhandler_java_maple",
+# "bytrace:bytrace_maple_java",
+# "ces:commonevent_base_java_maple",
+# "ces:commoneventkit_java_maple",
+# "dmsadapter:uri_java_maple",
+# "graphic:agp_maple_java",
+# "graphic:agpwindowkit_maple_java",
+# "graphic:surfaceviewadapter_maple_java",
+# "hilog:hilog_maple_java",
+# "intent:intent_java_maple",
+# "ipc:ipc_maple_java",
+# "ivicommon:drivingsafety_innerkit_maple_java",
+# "location:locationkits_maple_java",
+# "multimodalinput:mmi_event_maple_java",
+# "multimodalinput:mmi_eventimpl_maple_java",
+# "resmgr:kits_maple_java",
+# "startup:syspara_maple_java",
+# "utils:utils_java",
+# "utils:utils_maple_java",
+# ]
+
+# so_name = "multimedia"
+
+# subsystem_name = "multimedia"
+#}
+
+group("image_framework") {
+ deps = [
+# "adapter/frameworks/bitmapconverter/native:bitmapconverter",
+ "frameworks/innerkitsimpl/utils:image_utils",
+ "interfaces/innerkits:image",
+ #"interfaces/kits/native:multimedia_target",
+ ]
+}
+
+group("plugins") {
+ deps = [
+ "plugins/common/libs:multimediaplugin",
+ "plugins/manager:pluginmanager",
+ ]
+
+}
+
+#group("image_test_list") {
+# testonly = true
+
+ # image
+# deps = [
+# "adapter/frameworks/bitmapconverter/java/test:unittest",
+# "frameworks/innerkitsimpl/test:unittest",
+# "interfaces/kits/java/test:unittest",
+# "interfaces/kits/native/test:unittest",
+# "plugins/manager/test/unittest/common:unittest",
+# ]
+#}
+#group("image_performance_test_list") {
+# testonly = true
+# deps = [ "interfaces/kits/java/test/:performance" ]
+#}
+
+config("media_config") {
+ defines = []
+ #if (current_cpu == "arm64" || (current_cpu == "arm" && arm_use_neon)) {
+ if (current_cpu == "arm64" || (current_cpu == "arm")) {
+ defines += [ "USE_NEON" ]
+ }
+}
diff --git a/LICENSE b/LICENSE
new file mode 100755
index 0000000000000000000000000000000000000000..2bb9ad240fa04c8cf706a4901c4807878e90c2dc
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,176 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/OAT.xml b/OAT.xml
new file mode 100755
index 0000000000000000000000000000000000000000..7de7b0b657a32ce36ffb9d5ae3fd50eede1bbe17
--- /dev/null
+++ b/OAT.xml
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
old mode 100644
new mode 100755
index 0781a0f05b76db30b991282c699ec17b295b624b..c33fd63fdbecac7a8d6bc1b0406777e73bcfce9d
--- a/README.md
+++ b/README.md
@@ -1,39 +1,203 @@
-# multimedia_image_standard
+# Image
-#### 介绍
-{**以下是 Gitee 平台说明,您可以替换此简介**
-Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
-无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
+- [Introduction](#section11660541593)
+- [Directory Structure](#section161941989596)
+- [Usage](#section1312121216216)
+ - [Available APIs](#section1551164914237)
+ - [Usage Guidelines](#section129654513264)
-#### 软件架构
-软件架构说明
+- [Repositories Involved](#section1533973044317)
+## Introduction
-#### 安装教程
+The **image** repository provides easy-to-use APIs for developing image encoding and decoding features. Currently, the following image formats are supported: JPEG, PNG, BMP, WEBP, GIF, HEIF, and RAW.
-1. xxxx
-2. xxxx
-3. xxxx
+**Figure 1** Image architecture
+
-#### 使用说明
+## Directory Structure
-1. xxxx
-2. xxxx
-3. xxxx
+The structure of the repository directory is as follows:
-#### 参与贡献
+```
+/foundation/multimedia/image
+├── adapter # Adaptation code
+│ ├── frameworks # Framework adaptation
+│ └── hals # HAL adaptation
+├── frameworks # Framework code
+│ ├── innerkitsimpl # Native API implementation
+│ └── jni # JNI implementation
+├── ohos.build # Build configuration
+├── interfaces # External APIs
+│ ├── innerkits # APIs of other internal subsystems
+│ ├── kits # Java APIs
+│ └── native # NDK APIs
+├── mock # Mock implementation
+├── plugins # Image plug-in implementation
+│ ├── common # Common image plug-ins
+│ ├── manager # Image plug-in manager
+├── test # Test resources
+```
-1. Fork 本仓库
-2. 新建 Feat_xxx 分支
-3. 提交代码
-4. 新建 Pull Request
+## Usage
+### Available APIs
-#### 特技
+Major methods in **ImageSource**
+
+
+
Method
+ |
+Description
+ |
+
+
+create(String pathName, SourceOptions opts)
+ |
+Creates an ImageSource based on an image file path.
+ |
+
+create(InputStream is, SourceOptions opts)
+ |
+Creates an ImageSource based on an input stream.
+ |
+
+create(byte[] data, SourceOptions opts)
+ |
+Creates an ImageSource based on a byte array.
+ |
+
+create(byte[] data, int offset, int length, SourceOptions opts)
+ |
+Creates an ImageSource based on a byte array with specified offset and length.
+ |
+
+create(File file, SourceOptions opts)
+ |
+Creates an ImageSource based on a File object.
+ |
+
+create(FileDescriptor fd, SourceOptions opts)
+ |
+Creates an ImageSource based on a file descriptor.
+ |
+
+createIncrementalSource(SourceOptions opts)
+ |
+Creates an incremental data source based on a SourceOptions object.
+ |
+
+createIncrementalSource(IncrementalSourceOptions opts)
+ |
+Creates an incremental data source based on an IncrementalSourceOptions object.
+ |
+
+createPixelmap(DecodingOptions opts)
+ |
+Decodes source image data and creates a pixel map.
+ |
+
+createPixelmap(int index, DecodingOptions opts)
+ |
+Decodes source image data based on a specified index location in the ImageSource and creates a pixel map.
+ |
+
+release()
+ |
+Releases local resources associated with the PixelMap object.
+ |
+
+
+
+
+Major methods in **PixelMap**
+
+
+Method
+ |
+Description
+ |
+
+
+create(InitializationOptions opts)
+ |
+Creates a pixel map based on initialization options (such as the image size, pixel format, and alpha type).
+ |
+
+create(PixelMap source, Rect srcRegion, InitializationOptions opts)
+ |
+Creates a pixel map based on initialization options (such as the image size, pixel format, and alpha type) and the data source described by a source pixel map and the expected area on it.
+ |
+
+getBytesNumberPerRow()
+ |
+Obtains the number of bytes in each row of pixels.
+ |
+
+getPixelBytesCapacity()
+ |
+Obtains the memory capacity for storing the pixels of this pixel map.
+ |
+
+readPixel(Position pos)
+ |
+Reads the color value at the specified position. The color value is in PixelFormat.ARGB_8888 format.
+ |
+
+readPixels(int[] pixels, int offset, int stride, Rect region)
+ |
+Reads the color values of a specified region and writes them into a pixels array with the specified start offset and stride. The color values are in PixelFormat.ARGB_8888 format.
+ |
+
+readPixels(Buffer dst)
+ |
+Reads a copy of color values of this PixelMap instance and stores it to the specified buffer.
+ |
+
+writePixels(int[] pixels, int offset, int stride, Rect region)
+ |
+Writes data from the specified color data array (based on the start offset and stride) into the specified region of this PixelMap instance. The color data to write is in PixelFormat.ARGB_8888 format.
+ |
+
+writePixels(Buffer src)
+ |
+Writes the pixel data in the specified buffer into this PixelMap. The buffer data will overwrite the PixelMap data, so the color format of the source data must be compatible with this PixelMap.
+ |
+
+getImageInfo()
+ |
+Obtains basic image information.
+ |
+
+release()
+ |
+Releases local resources associated with the PixelMap object.
+ |
+
+
+
+
+### Usage Guidelines
+
+The following example shows how to parse a local image by calling methods in **ImageSource**:
+
+```
+ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
+srcOpts.formatHint = "image/png";
+String pathName = "/sdcard/image.png";
+ImageSource imageSource = ImageSource.create(pathName, srcOpts);
+ImageSource imageSourceNoOptions = ImageSource.create(pathName, null);
+// Common decoding with scaling, cropping, and rotation
+ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+decodingOpts.desiredSize = new Size(100, 2000);
+decodingOpts.desiredRegion = new Rect(0, 0, 100, 100);
+decodingOpts.rotateDegrees = 90;
+PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
+// Common decoding mode
+PixelMap pixelMapNoOptions = imageSource.createPixelmap(null);
+```
+
+## Repositories Involved
+
+hmf/multimedia/image
-1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
-2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
-3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
-4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
-5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
-6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
diff --git a/README_zh.md b/README_zh.md
new file mode 100755
index 0000000000000000000000000000000000000000..deccb87b7a516109255cdfcca461676964bd9cc6
--- /dev/null
+++ b/README_zh.md
@@ -0,0 +1,203 @@
+# Image组件
+
+- [简介](#section11660541593)
+- [目录](#section161941989596)
+- [说明](#section1312121216216)
+ - [接口说明](#section1551164914237)
+ - [使用说明](#section129654513264)
+
+- [相关仓](#section1533973044317)
+
+## 简介
+
+Image组件提供了简单易用的接口用于开发图像的编解码功能,目前支持主流的如下图片格式:JPEG、PNG、BMP、WEBP、GIF、HEIF、RAW。
+
+**图 1** Image组件架构图
+
+
+## 目录
+
+仓目录结构如下:
+
+```
+/foundation/multimedia/image # Image组件业务代码
+├── adapter # 适配层代码
+│ └── frameworks # 框架适配层
+│ └── hals # hal适配层
+├── frameworks # 框架代码
+│ ├── innerkitsimpl # 框架native层业务实现
+│ └── jni # jni层实现
+├── ohos.build # 编译配置
+├── interfaces # 外部接口层
+│ ├── innerkits # 内部其他子系统接口
+│ ├── kits # java接口层
+│ └── native # ndk接口层
+├── mock # mock实现
+├── plugins # 图像插件实现
+│ ├── common # 图像通用插件
+│ └── manager # 图像插件管理模块
+├── test # 测试资源目录
+```
+
+## 说明
+
+### 接口说明
+
+ImageSource提供的主要接口如下:
+
+
+接口名
+ |
+描述
+ |
+
+
+create(String pathName, SourceOptions opts)
+ |
+从图像文件路径创建图像数据源。
+ |
+
+create(InputStream is, SourceOptions opts)
+ |
+从输入流创建图像数据源。
+ |
+
+create(byte[] data, SourceOptions opts)
+ |
+从字节数组创建图像源。
+ |
+
+create(byte[] data, int offset, int length, SourceOptions opts)
+ |
+从字节数组指定范围创建图像源。
+ |
+
+create(File file, SourceOptions opts)
+ |
+从文件对象创建图像数据源。
+ |
+
+create(FileDescriptor fd, SourceOptions opts)
+ |
+从文件描述符创建图像数据源。
+ |
+
+createIncrementalSource(SourceOptions opts)
+ |
+创建渐进式图像数据源。
+ |
+
+createIncrementalSource(IncrementalSourceOptions opts)
+ |
+创建渐进式图像数据源,支持设置渐进式数据更新模式。
+ |
+
+createPixelmap(DecodingOptions opts)
+ |
+从图像数据源解码并创建PixelMap图像。
+ |
+
+createPixelmap(int index, DecodingOptions opts)
+ |
+从图像数据源解码并创建PixelMap图像,如果图像数据源支持多张图片的话,支持指定图像索引。
+ |
+
+release()
+ |
+释放对象关联的本地资源。
+ |
+
+
+
+
+PixelMap提供的主要接口如下:
+
+
+接口名
+ |
+描述
+ |
+
+
+create(InitializationOptions opts)
+ |
+根据图像大小、像素格式、alpha类型等初始化选项创建PixelMap。
+ |
+
+create(PixelMap source, Rect srcRegion, InitializationOptions opts)
+ |
+根据图像大小、像素格式、alpha类型等初始化选项,以源PixelMap、源裁剪区域描述的数据源创建PixelMap。
+ |
+
+getBytesNumberPerRow()
+ |
+获取每行像素数据占用的字节数。
+ |
+
+getPixelBytesCapacity()
+ |
+获取存储Pixelmap像素数据的内存容量。
+ |
+
+readPixel(Position pos)
+ |
+读取指定位置像素的颜色值,返回的颜色格式为PixelFormat.ARGB_8888。
+ |
+
+readPixels(int[] pixels, int offset, int stride, Rect region)
+ |
+读取指定区域像素的颜色值,输出到以起始偏移量、行像素大小描述的像素数组,返回的颜色格式为PixelFormat.ARGB_8888。
+ |
+
+readPixels(Buffer dst)
+ |
+读取像素的颜色值到缓冲区,返回的数据是PixelMap中像素数据的原样拷贝,即返回的颜色数据格式与PixelMap中像素格式一致。
+ |
+
+writePixels(int[] pixels, int offset, int stride, Rect region)
+ |
+将像素颜色数组、起始偏移量、行像素的个数描述的源像素数据写入PixelMap的指定区域,写入颜色格式为PixelFormat.ARGB_8888。
+ |
+
+writePixels(Buffer src)
+ |
+将缓冲区描述的源像素数据写入PixelMap,写入的数据将原样覆盖PixelMap中的像素数据,即写入数据的颜色格式应与PixelMap的配置兼容。
+ |
+
+getImageInfo()
+ |
+获取图像基本信息。
+ |
+
+release()
+ |
+释放对象关联的本地资源。
+ |
+
+
+
+
+### 使用说明
+
+下面提供了使用ImageSource解析本地图片的例子:
+
+```
+ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
+srcOpts.formatHint = "image/png";
+String pathName = "/sdcard/image.png";
+ImageSource imageSource = ImageSource.create(pathName, srcOpts);
+ImageSource imageSourceNoOptions = ImageSource.create(pathName, null);
+// 普通解码叠加缩放、裁剪、旋转
+ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+decodingOpts.desiredSize = new Size(100, 2000);
+decodingOpts.desiredRegion = new Rect(0, 0, 100, 100);
+decodingOpts.rotateDegrees = 90;
+PixelMap pixelMap = imageSource.createPixelmap(decodingOpts);
+// 普通模式解码
+PixelMap pixelMapNoOptions = imageSource.createPixelmap(null);
+```
+
+## 相关仓
+
+hmf/multimedia/image
+
diff --git a/adapter/LICENSE b/adapter/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..3d9b23b82406505acfa2c506609c121e74e57711
--- /dev/null
+++ b/adapter/LICENSE
@@ -0,0 +1,44 @@
+Copyright (C) 2021 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.
+
+***************************************************************
+android permission, multimedia, it is derived from the following:
+https://android.googlesource.com/platform/frameworks/base/
+version 10.0.0_r2
+***************************************************************
+Copyright 2005-2008 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+
+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.
+
+***************************************************************
+heif, it is derived from the following:
+https://android.googlesource.com/platform/frameworks/av/
+version 10.0.0_r2
+***************************************************************
+Copyright 2005-2008 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+
+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.
\ No newline at end of file
diff --git a/adapter/frameworks/bitmapconverter/java/BUILD.gn b/adapter/frameworks/bitmapconverter/java/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..2a7a2306f01106a9e287dcfd59b3ecb90e9c5a1d
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/java/BUILD.gn
@@ -0,0 +1,49 @@
+# Copyright (C) 2021 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("//build/config/ohos/rules.gni")
+
+java_library("imagesystemadapter_java") {
+ java_files = [ "src/ohos/media/image/inner/ImageDoubleFwConverter.java" ]
+
+ classpath_deps = [
+ "//foundation/multimedia/image/interfaces/kits/java:image_java",
+ "//foundation/multimedia/utils/java:multimedia_utils_java",
+ ]
+
+ external_deps = [
+ "ipc:ipc_java",
+ "utils:utils_java",
+ ]
+ part_name = "multimedia_image"
+}
+
+ohos_maple_java("imagesystemadapter_maple_java") {
+ deps = [
+ ":imagesystemadapter_java",
+ "//foundation/multimedia/image/interfaces/kits/java:image_maple_java",
+ "//foundation/multimedia/utils/java:multimedia_utils_maple_java",
+ "//utils/java:utils_java",
+ "//utils/java:utils_maple_java",
+ ]
+
+ aosp_deps = [ "maple:framework" ]
+
+ external_deps = [
+ "hilog:hilog_maple_java",
+ "ipc:ipc_java",
+ "utils:utils_maple_java",
+ ]
+
+ subsystem_name = "multimedia"
+}
diff --git a/adapter/frameworks/bitmapconverter/java/src/ohos/media/image/inner/ImageDoubleFwConverter.java b/adapter/frameworks/bitmapconverter/java/src/ohos/media/image/inner/ImageDoubleFwConverter.java
new file mode 100644
index 0000000000000000000000000000000000000000..5880725b2581e1ef111bf467cd8fc9c6cf78de6c
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/java/src/ohos/media/image/inner/ImageDoubleFwConverter.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2006 The Android Open Source Project
+ * 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.
+ */
+
+package ohos.media.image.inner;
+
+import android.graphics.Bitmap;
+
+import ohos.utils.Parcel;
+import ohos.rpc.MessageParcel;
+import ohos.media.image.PixelMap;
+import ohos.media.utils.log.Logger;
+import ohos.media.utils.log.LoggerFactory;
+
+/**
+ * Bitmap and PixelMap Converter
+ *
+ * @since 1
+ */
+public class ImageDoubleFwConverter {
+ private static final Logger LOGGER = LoggerFactory.getImageLogger(ImageDoubleFwConverter.class);
+
+ static {
+ LOGGER.debug("Begin loading image_converter_jni library");
+ try {
+ System.loadLibrary("image_converter_jni.z");
+ } catch (UnsatisfiedLinkError | NullPointerException e) {
+ LOGGER.error("loadLibrary image_converter_jni.z fail");
+ }
+ }
+
+ /**
+ * convert PixelMap to Bitmap
+ *
+ * @param pixelMap create form source image
+ * @return android Bitmap on success, otherwise return null
+ * @since 1
+ */
+ public static Bitmap createShadowBitmap(PixelMap pixelMap) {
+ if (pixelMap == null) {
+ LOGGER.error("createShadowBitmap pixelMap is null");
+ return null;
+ }
+
+ return nativeCreateBitmap(pixelMap);
+ }
+
+ /**
+ * Convert Bitmap to PixelMap
+ *
+ * @param bitmap android's Bitmap object
+ * @return PixelMap on success, otherwise return null
+ * @since 1
+ */
+ public static PixelMap createShellPixelMap(Bitmap bitmap) {
+ if (bitmap == null) {
+ LOGGER.error("createShellPixelMap bitmap is null");
+ return null;
+ }
+
+ return nativeCreatePixelMap(bitmap);
+ }
+
+ /**
+ * Write PixelMap to Parcel
+ *
+ * @param pixelMap source image
+ * @param parcel ohos parcel object
+ * @since 3
+ */
+ public static void writeToParcel(PixelMap pixelMap, Parcel parcel) {
+ if (pixelMap == null) {
+ LOGGER.error("writeToParcel pixelMap is null");
+ return;
+ }
+
+ if (parcel instanceof MessageParcel) {
+ nativeWriteToParcel(pixelMap, parcel);
+ } else {
+ LOGGER.error("writeToParcel not a MessageParcel");
+ }
+ }
+
+ private static native Bitmap nativeCreateBitmap(PixelMap pixelMap);
+
+ private static native PixelMap nativeCreatePixelMap(Bitmap bitmap);
+
+ private static native void nativeWriteToParcel(PixelMap pixelMap, Parcel parcel);
+}
diff --git a/adapter/frameworks/bitmapconverter/java/test/BUILD.gn b/adapter/frameworks/bitmapconverter/java/test/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..63ca42a1b049aa8f541ef9eb20512f7a25c7ab82
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/java/test/BUILD.gn
@@ -0,0 +1,43 @@
+# Copyright (C) 2021 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("//build/test.gni")
+
+module_output_path = "multimedia_image/image_standard"
+
+#ohos_java_unittest("test_imagesystemadapter_java_maple") {
+# java_files =
+# [ "unittest/src/ohos/media/image/inner/ImageDoubleFwConverterTest.java" ]
+#
+# deps = [
+# "//foundation/multimedia/image/adapter/frameworks/bitmapconverter/java:imagesystemadapter_maple_java",
+# "//foundation/multimedia/image/interfaces/kits/java:image_maple_java",
+# "//foundation/multimedia/utils/java:multimedia_utils_maple_java",
+# "//utils/java:utils_java",
+# "//utils/java:utils_maple_java",
+# ]
+
+# external_deps = [
+# "ipc:ipc_java",
+# "utils:utils_maple_java",
+# ]
+
+# sub_output_dir = "$module_output_path/"
+# resource_config_file =
+# "//foundation/multimedia/image/test/resource/image/ohos_test.xml"
+#}
+
+#group("unittest") {
+# testonly = true
+# deps = [ ":test_imagesystemadapter_java_maple" ]
+#}
diff --git a/adapter/frameworks/bitmapconverter/java/test/unittest/src/ohos/media/image/inner/ImageDoubleFwConverterTest.java b/adapter/frameworks/bitmapconverter/java/test/unittest/src/ohos/media/image/inner/ImageDoubleFwConverterTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..ea5aab6149b9167101024e13df40a90744e99b76
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/java/test/unittest/src/ohos/media/image/inner/ImageDoubleFwConverterTest.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2007 The Android Open Source Project
+ * 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.
+ */
+
+package ohos.media.image.inner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Parcel;
+
+import ohos.media.image.ImageSource;
+import ohos.media.image.PixelMap;
+import ohos.media.image.common.AllocatorType;
+import ohos.media.image.common.PixelFormat;
+import ohos.media.image.common.Position;
+import ohos.media.image.common.Rect;
+import ohos.media.image.common.Size;
+import ohos.rpc.MessageParcel;
+import ohos.media.utils.log.Logger;
+import ohos.media.utils.log.LoggerFactory;
+import ohos.unittest.CaseLevel;
+import ohos.unittest.CaseType;
+import ohos.unittest.Level;
+import ohos.unittest.Type;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * ImageDoubleFwConverterTest, test cases for ImageDoubleFwConverter class,
+ * mainly including test cases for PixelMap and Bitmap conversion.
+ *
+ * @since 1
+ */
+public class ImageDoubleFwConverterTest {
+ private static final Logger LOGGER = LoggerFactory.getImageLogger(ImageDoubleFwConverterTest.class);
+
+ private static File pngFile;
+
+ static {
+ try {
+ System.loadLibrary("ipc_core.z");
+ } catch (UnsatisfiedLinkError | NullPointerException e) {
+ LOGGER.error("loadLibrary ipc_core.z fail");
+ }
+ }
+
+ private ImageSource imageSource;
+
+ private PixelMap pixelMap;
+
+ private ImageDoubleFwConverter converter = new ImageDoubleFwConverter();
+
+ /**
+ * Action before all test case.
+ */
+ @BeforeClass
+ public static void setUpBeforeClass() throws Exception {
+ pngFile = new File("/sdcard/multimedia/image/test.png");
+ if (!pngFile.exists()) {
+ LOGGER.error("test file not exist.");
+ fail("files not exist");
+ }
+ }
+
+ /**
+ * Action after all test case.
+ */
+ @AfterClass
+ public static void tearDownAfterClass() throws Exception {
+ }
+
+ /**
+ * Action before test case.
+ */
+ @Before
+ public void setUp() throws Exception {
+ }
+
+ /**
+ * Action after test case.
+ */
+ @After
+ public void tearDown() throws Exception {
+ try {
+ if (imageSource != null) {
+ imageSource.release();
+ imageSource = null;
+ }
+ if (pixelMap != null) {
+ pixelMap.release();
+ pixelMap = null;
+ }
+ } catch (Throwable throwable) {
+ LOGGER.error("test case teardown fail, %{public}s", throwable.getMessage());
+ }
+ }
+
+ /**
+ * @tc.name: testImageDoubleFwConverter001
+ * @tc.desc: convert between Bitmap and PixelMap.
+ */
+ @Test
+ @CaseLevel(level = Level.LEVEL_3)
+ @CaseType(type = Type.FUNC)
+ public void testImageDoubleFwConverter001() {
+ /**
+ * @tc.steps: step1.get pixelmap from path.
+ * @tc.expected: step1.get image source form path not null
+ */
+ ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
+ srcOpts.formatHint = "image/png";
+ String pathName = "/sdcard/multimedia/image/test.png";
+ imageSource = ImageSource.create(pathName, srcOpts);
+ assertNotNull(imageSource);
+
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.desiredSize = new Size(0, 0);
+ decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
+ decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
+ pixelMap = imageSource.createPixelmap(decodingOpts);
+ assertNotNull(pixelMap);
+
+ /**
+ * @tc.steps: step2.convert pixelmap to bitmap and convert bitmap to pixelmap back.
+ * @tc.expected: step2.conversion ok
+ */
+ Bitmap bitmap = ImageDoubleFwConverter.createShadowBitmap(pixelMap);
+ assertNotNull(bitmap);
+ assertNotNull(bitmap.getConfig());
+
+ Bitmap bitmap1 = bitmap.copy(bitmap.getConfig(), false);
+ assertNotNull(bitmap1);
+
+ Bitmap bitmap2 = BitmapFactory.decodeFile(pathName);
+ PixelMap pixelMapNew = ImageDoubleFwConverter.createShellPixelMap(bitmap2);
+ assertNotNull(pixelMapNew);
+
+ assertEquals(472, pixelMapNew.getImageInfo().size.width);
+ assertEquals(75, pixelMapNew.getImageInfo().size.height);
+ }
+
+ /**
+ * @tc.name: testImageDoubleFwConverter002
+ * @tc.desc: convert between Bitmap and PixelMap.
+ */
+ @Test
+ @CaseLevel(level = Level.LEVEL_3)
+ @CaseType(type = Type.FUNC)
+ public void testImageDoubleFwConverter002() {
+ /**
+ * @tc.steps: step1.get pixelmap from path.
+ * @tc.expected: step1.get image source form path not null
+ */
+ ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
+ srcOpts.formatHint = "image/png";
+ String pathName = "/sdcard/multimedia/image/test_large.webp";
+ imageSource = ImageSource.create(pathName, srcOpts);
+ assertNotNull(imageSource);
+
+ /**
+ * @tc.steps: step2.decode pixelmap.
+ * @tc.expected: step2.decode ok
+ */
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.desiredSize = new Size(0, 0);
+ decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
+ decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
+ pixelMap = imageSource.createPixelmap(decodingOpts);
+ assertNotNull(pixelMap);
+
+ /**
+ * @tc.steps: step3.read pixel map by pos.
+ * @tc.expected: step3.read ok
+ */
+ int zColor = pixelMap.readPixel(new Position(360, 342));
+ byte[] zBytes = new byte[4];
+ zBytes[3] = (byte) (zColor & 0xff); // B 87
+ zBytes[2] = (byte) (zColor >> 8 & 0xff); // G 248
+ zBytes[1] = (byte) (zColor >> 16 & 0xff); // R 243
+ zBytes[0] = (byte) (zColor >> 24 & 0xff); // A 255
+
+ assertEquals(zBytes[0], (byte)-1);
+ assertEquals(zBytes[1], (byte)63);
+ assertEquals(zBytes[2], (byte)71);
+ assertEquals(zBytes[3], (byte)-51);
+
+ /**
+ * @tc.steps: step4.convert pixelmap to bitmap and read same pos.
+ * @tc.expected: step4.pixelmap's color is same of bitmap's color
+ */
+ Bitmap bitmap = ImageDoubleFwConverter.createShadowBitmap(pixelMap);
+ assertNotNull(bitmap);
+ assertNotNull(bitmap.getConfig());
+ int aColor = bitmap.getPixel(360, 342);
+ assertEquals(zColor, aColor);
+
+ /**
+ * @tc.steps: step5.convert bitmap to pixelmap and read same pos.
+ * @tc.expected: step5.pixelmapback's color is same of pixelmap's color
+ */
+ PixelMap pixelMapBack = ImageDoubleFwConverter.createShellPixelMap(bitmap);
+ int zColorBack = pixelMapBack.readPixel(new Position(360, 342));
+ assertEquals(zColor, zColorBack);
+
+ /**
+ * @tc.steps: step6.copy bitmap and read same pos.
+ * @tc.expected: step6.bitmapcopy's color is same of pixelmap's color
+ */
+ Bitmap bitmap1 = bitmap.copy(bitmap.getConfig(), false);
+ assertNotNull(bitmap1);
+ int colorCopy = bitmap1.getPixel(360, 342);
+ assertEquals(zColor, colorCopy);
+ assertEquals(aColor, colorCopy);
+
+ /**
+ * @tc.steps: step7.decode bitmap and convert to pixelmap then read same pos.
+ * @tc.expected: step7.bitmap's color is same of pixelmap's color
+ */
+ Bitmap bitmap2 = BitmapFactory.decodeFile(pathName);
+ PixelMap pixelMapNew = ImageDoubleFwConverter.createShellPixelMap(bitmap2);
+ assertNotNull(pixelMapNew);
+ int aColor2 = bitmap2.getPixel(360, 342);
+ int zColor2 = pixelMapNew.readPixel(new Position(360, 342));
+ assertEquals(aColor2, zColor2);
+ }
+
+ /**
+ * @tc.name: testImageDoubleFwConverter003
+ * @tc.desc: PixelMap write to parcel.
+ */
+ @Test
+ @CaseLevel(level = Level.LEVEL_3)
+ @CaseType(type = Type.FUNC)
+ public void testImageDoubleFwConverter003() {
+ /**
+ * @tc.steps: step1.get pixelmap from path.
+ * @tc.expected: step1.get image source form path not null
+ */
+ ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
+ srcOpts.formatHint = "image/png";
+ String pathName = "/sdcard/multimedia/image/test_large.webp";
+ imageSource = ImageSource.create(pathName, srcOpts);
+ assertNotNull(imageSource);
+
+ /**
+ * @tc.steps: step2.create pixelmap and bitmap.
+ * @tc.expected: step2.create ok
+ */
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.desiredSize = new Size(0, 0);
+ decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
+ decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
+ pixelMap = imageSource.createPixelmap(decodingOpts);
+ assertNotNull(pixelMap);
+ Bitmap bitmap = ImageDoubleFwConverter.createShadowBitmap(pixelMap);
+ assertNotNull(bitmap);
+
+ /**
+ * @tc.steps: step3.write bitmap to android parcel, pixelMap to MessageParcel, compare size.
+ * @tc.expected: step3.size equals
+ */
+ android.os.Parcel aParcel = android.os.Parcel.obtain();
+ bitmap.writeToParcel(aParcel, 0);
+ int aParcelSize = aParcel.dataSize();
+
+ MessageParcel zParcel = MessageParcel.obtain();
+ ImageDoubleFwConverter.writeToParcel(pixelMap, zParcel);
+ int zParcelSize = zParcel.getSize();
+
+ assertEquals(zParcelSize, aParcelSize);
+
+ aParcel.recycle();
+ zParcel.reclaim();
+ }
+
+ /**
+ * @tc.name: testImageDoubleFwConverter004
+ * @tc.desc: PixelMap write to parcel using shared memory.
+ */
+ @Test
+ @CaseLevel(level = Level.LEVEL_3)
+ @CaseType(type = Type.FUNC)
+ public void testImageDoubleFwConverter004() {
+ /**
+ * @tc.steps: step1.get pixelmap from path.
+ * @tc.expected: step1.get image source form path not null
+ */
+ ImageSource.SourceOptions srcOpts = new ImageSource.SourceOptions();
+ srcOpts.formatHint = "image/png";
+ String pathName = "/sdcard/multimedia/image/test.png";
+ imageSource = ImageSource.create(pathName, srcOpts);
+ assertNotNull(imageSource);
+
+ /**
+ * @tc.steps: step2.create pixelmap and bitmap.
+ * @tc.expected: step2.create ok
+ */
+ ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
+ decodingOpts.desiredSize = new Size(0, 0);
+ decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
+ decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
+ decodingOpts.allocator = AllocatorType.SHARED_MEMORY;
+ pixelMap = imageSource.createPixelmap(decodingOpts);
+ assertNotNull(pixelMap);
+
+ Bitmap bitmap = ImageDoubleFwConverter.createShadowBitmap(pixelMap);
+ assertNotNull(bitmap);
+
+ assertEquals(Bitmap.Config.ARGB_8888, bitmap.getConfig());
+ assertEquals(472, bitmap.getWidth());
+ assertEquals(75, bitmap.getHeight());
+
+ int pixelMapDataSize = (int) pixelMap.getPixelBytesCapacity();
+ ByteBuffer pixelMapByteBuffer = ByteBuffer.allocate(pixelMapDataSize);
+ pixelMap.readPixels(pixelMapByteBuffer);
+
+ int bitMapdataSize = bitmap.getByteCount();
+ ByteBuffer bitmapByteBuffer = ByteBuffer.allocate(bitMapdataSize);
+ bitmap.copyPixelsToBuffer(bitmapByteBuffer);
+
+ assertEquals(0, pixelMapByteBuffer.compareTo(bitmapByteBuffer));
+ }
+
+}
diff --git a/adapter/frameworks/bitmapconverter/native/BUILD.gn b/adapter/frameworks/bitmapconverter/native/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..8fd57b81964a4315ccd2ffd9b65f3df7b8605fc4
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/BUILD.gn
@@ -0,0 +1,207 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+import("//foundation/multimedia/image_standard/ide/image_decode_config.gni")
+
+#config("bitmapconverter_public_config") {
+# visibility = [ ":*" ]
+# include_dirs = [
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/private",
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/android",
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/gpu",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/frameworks/base/libs/hwui/hwui",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/frameworks/native/libs/nativewindow/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/frameworks/native/libs/arect/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/system/core/libcutils/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/frameworks/native/libs/ui/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/frameworks/native/libs/nativebase/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/system/core/libsystem/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/system/core/libutils/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/hardware/libhardware/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/hardware/libhardware/include",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/system/core/liblog/include",
+# ]
+
+# if (use_mingw_win) {
+# include_dirs += [
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/external/skia/include/config/win",
+# "${asdk_dir}/shared_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+# ]
+# } else {
+# include_dirs += [ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/android" ]
+# }
+#}
+
+ohos_shared_library("bitmapconverter") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native/src/bitmap_wrapper.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native/src/image_bitmap_converter.cpp",
+ ]
+
+# public_configs = [ ":bitmapconverter_public_config" ]
+
+ include_dirs = [
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native/include",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/include/encode",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/src/ports",
+ "//third_party/flutter/skia/src/images",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/third_party/externals/freetype/include/freetype",
+ "//third_party/flutter/skia/include/private",
+
+ ]
+
+ if (use_mingw_win) {
+ include_dirs += [ "//foundation/multimedia/image_standard/mock/native/include" ]
+
+ deps = [
+ "//foundation/multimedia/image_standard/interfaces/innerkits:static_image",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ ]
+
+ libs = [ "//foundation/multimedia/image_standard/libskia.a" ]
+ } else {
+ include_dirs += [
+ "//utils/native/base/include",
+# "//sdk/aosp-arm64/communication/ipc_core/include/",
+ ]
+
+ deps = [
+ "//foundation/multimedia/image_standard/interfaces/innerkits:image",
+ "//utils/native/base:utils",
+ ]
+
+# aosp_deps = [
+# "shared_library:libhwui",
+# "shared_library:liblog",
+# ]
+
+ external_deps = [
+ "hiviewdfx_hilog_native:libhilog",
+ "ipc:ipc_core",
+ ]
+ }
+
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
+
+ohos_static_library("static_bitmapconverter") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native/src/bitmap_wrapper.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native/src/image_bitmap_converter.cpp",
+ ]
+
+# public_configs = [ ":bitmapconverter_public_config" ]
+
+ include_dirs = [
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native/include",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/include/encode",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/src/ports",
+ "//third_party/flutter/skia/src/images",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/third_party/externals/freetype/include/freetype",
+ "//third_party/flutter/skia/include/private",
+
+ ]
+
+ if (use_mingw_win) {
+ include_dirs += [ "//foundation/multimedia/image_standard/mock/native/include" ]
+
+ deps = [
+ "//foundation/multimedia/image_standard/interfaces/innerkits:static_image",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ ]
+
+ libs = [ "//foundation/multimedia/image_standard/libskia.a" ]
+ } else {
+ include_dirs += [
+ "//utils/native/base/include",
+# "//sdk/aosp-arm64/communication/ipc_core/include/",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ ]
+
+ deps = [
+ "//foundation/multimedia/image_standard/interfaces/innerkits:image",
+ "//utils/native/base:utils",
+ ]
+
+# aosp_deps = [
+# "shared_library:libhwui",
+# "shared_library:liblog",
+# ]
+
+ external_deps = [
+ "hiviewdfx_hilog_native:libhilog",
+ "ipc:ipc_core",
+ ]
+ }
+}
+
+#config("image_converter_jni_config") {
+# visibility = [ ":*" ]
+# include_dirs = [
+# "//utils/native/base/include",
+# "//utils/jni/jnikit/include",
+# "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/include",
+# "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+# "//foundation/multimedia/image_standard/plugins/manager/include",
+# "//foundation/multimedia/utils/include",
+# "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native/include",
+# ]
+#}
+
+#group("g_image_converter_jni") {
+# deps = [ ":image_converter_jni" ]
+#}
+
+#ohos_shared_library("image_converter_jni") {
+# sources = [
+# "src/image_native_interface_utils.cpp",
+# "src/ohos_image_ImageDoubleFwConverter.cpp",
+# ]
+
+# configs = [ ":image_converter_jni_config" ]
+
+# include_dirs = [ "//sdk/aosp-arm64/communication/ipc_core/include/" ]
+
+# deps = [
+# "//foundation/multimedia/image_standard/adapter/frameworks/bitmapconverter/native:bitmapconverter",
+# "//foundation/multimedia/image_standard/interfaces/innerkits:image",
+# "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+# "//utils/jni:utils_jnikit",
+# "//utils/native/base:utils",
+# ]
+
+# external_deps = [
+# "hilog:libhilog",
+# "ipc:ipc_core",
+# ]
+# subsystem_name = "multimedia"
+# part_name = "multimedia_image"
+#}
diff --git a/adapter/frameworks/bitmapconverter/native/include/bitmap_wrapper.h b/adapter/frameworks/bitmapconverter/native/include/bitmap_wrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..3b15f9c286abc0f82c93ec662b4f3561da55e6f7
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/include/bitmap_wrapper.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2015 The Android Open Source Project
+ * 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 BITMAP_WRAPPER_H
+#define BITMAP_WRAPPER_H
+
+#include "Bitmap.h"
+#include "SkBitmap.h"
+
+namespace android {
+class BitmapWrapper {
+public:
+ BitmapWrapper(android::Bitmap *bitmap) : mBitmap(bitmap) {}
+ ~BitmapWrapper() {}
+ void freePixels();
+ bool valid() const;
+ android::Bitmap &bitmap();
+ void assertValid() const;
+ void getSkBitmap(SkBitmap *outBitmap) const;
+ bool hasHardwareMipMap();
+ void setHasHardwareMipMap(bool hasMipMap);
+ void setAlphaType(SkAlphaType alphaType);
+ const SkImageInfo &info();
+ size_t getAllocationByteCount() const;
+ size_t rowBytes() const;
+ uint32_t getGenerationID() const;
+ bool isHardware();
+
+private:
+ sk_sp mBitmap = nullptr;
+ SkImageInfo mInfo;
+ bool mHasHardwareMipMap = false;
+ size_t mAllocationSize = 0;
+ size_t mRowBytes = 0;
+ uint32_t mGenerationId = 0;
+ bool mIsHardware = false;
+};
+} // namespace android
+#endif // BITMAP_WRAPPER_H
diff --git a/adapter/frameworks/bitmapconverter/native/include/hilog/log.h b/adapter/frameworks/bitmapconverter/native/include/hilog/log.h
new file mode 100644
index 0000000000000000000000000000000000000000..5515244b1e5dee5203ca0a3a0d66b9ca6f5bcc89
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/include/hilog/log.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2021 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 HIVIEWDFX_HILOG_H
+#define HIVIEWDFX_HILOG_H
+
+#include "hilog/log_c.h"
+#include "hilog/log_cpp.h"
+
+#endif // HIVIEWDFX_HILOG_H
\ No newline at end of file
diff --git a/adapter/frameworks/bitmapconverter/native/include/hilog/log_c.h b/adapter/frameworks/bitmapconverter/native/include/hilog/log_c.h
new file mode 100644
index 0000000000000000000000000000000000000000..d64551d00b4e706319c1d3bd824073a0be230c86
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/include/hilog/log_c.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2021 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 HIVIEWDFX_HILOG_C_H
+#define HIVIEWDFX_HILOG_C_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Log domain
+#ifndef LOG_DOMAIN
+#define LOG_DOMAIN 0
+#endif
+
+// Log tag
+#ifndef LOG_TAG
+#define LOG_TAG NULL
+#endif
+
+// Log type
+typedef enum {
+ LOG_TYPE_MIN = 0,
+ // Log to kmsg, only used by init phase.
+ LOG_INIT = 1,
+ // Used by core service, framework.
+ LOG_CORE = 3,
+ LOG_TYPE_MAX
+} LogType;
+
+// Log level
+typedef enum {
+ LOG_LEVEL_MIN = 0,
+ LOG_DEBUG = 3,
+ LOG_INFO = 4,
+ LOG_WARN = 5,
+ LOG_ERROR = 6,
+ LOG_FATAL = 7,
+ LOG_LEVEL_MAX,
+} LogLevel;
+
+int HiLogPrint(LogType type, LogLevel level, unsigned int domain, const char *tag, const char *fmt, ...)
+ __attribute__((__format__(os_log, 5, 6)));
+
+#define HILOG_DEBUG(type, ...) ((void)HiLogPrint((type), LOG_DEBUG, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
+
+#define HILOG_INFO(type, ...) ((void)HiLogPrint((type), LOG_INFO, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
+
+#define HILOG_WARN(type, ...) ((void)HiLogPrint((type), LOG_WARN, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
+
+#define HILOG_ERROR(type, ...) ((void)HiLogPrint((type), LOG_ERROR, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
+
+#define HILOG_FATAL(type, ...) ((void)HiLogPrint((type), LOG_FATAL, LOG_DOMAIN, LOG_TAG, __VA_ARGS__))
+
+bool HiLogIsLoggable(unsigned int domain, const char *tag, LogLevel level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HIVIEWDFX_HILOG_C_H
diff --git a/adapter/frameworks/bitmapconverter/native/include/hilog/log_cpp.h b/adapter/frameworks/bitmapconverter/native/include/hilog/log_cpp.h
new file mode 100644
index 0000000000000000000000000000000000000000..e27379231ddd78114695e7d4cead7535c8ce6235
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/include/hilog/log_cpp.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 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 HIVIEWDFX_HILOG_CPP_H
+#define HIVIEWDFX_HILOG_CPP_H
+
+#include "hilog/log_c.h"
+
+#ifdef __cplusplus
+
+namespace OHOS {
+namespace HiviewDFX {
+typedef struct HiLogLabel {
+ LogType type;
+ unsigned int domain;
+ const char *tag;
+} HiLogLabel;
+
+class HiLog final {
+public:
+ static int Debug(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
+ static int Info(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
+ static int Warn(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
+ static int Error(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
+ static int Fatal(const HiLogLabel &label, const char *fmt, ...) __attribute__((__format__(os_log, 2, 3)));
+};
+} // namespace HiviewDFX
+} // namespace OHOS
+#endif // __cplusplus
+#endif // HIVIEWDFX_HILOG_CPP_H
diff --git a/adapter/frameworks/bitmapconverter/native/include/image_bitmap_converter.h b/adapter/frameworks/bitmapconverter/native/include/image_bitmap_converter.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ec0fbf0b165e19298ec8407999815e9bebba877
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/include/image_bitmap_converter.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2015 The Android Open Source Project
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IMAGE_BITMAP_CONVERTER_H
+#define IMAGE_BITMAP_CONVERTER_H
+
+#include
+#include "bitmap_wrapper.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "pixel_map.h"
+#include "message_parcel.h"
+
+namespace OHOS {
+namespace Media {
+class ImageBitmapConverter {
+public:
+ static android::BitmapWrapper *CreateShadowBitmap(PixelMap *pixelMap);
+ static PixelMap *CreateShellPixelMap(android::BitmapWrapper *bitmapWrapper);
+ static void PixelMapWriteToParcel(PixelMap *pixelMap, int density, MessageParcel *parcel);
+ static PixelMap *createFromAlpha(PixelMap *pixelMapSrc);
+
+private:
+ static const size_t SIZE_LIMIT = 16 * 1024;
+ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "ImageBitmapConverter"
+ };
+ static SkColorType GetColorType(PixelFormat pixelFormat);
+ static void FreeBitmap(void *addr, void *context);
+ static PixelFormat GetPixelFormat(SkColorType colorType);
+ static void FreePixelMapFunc(void *addr, void *context, uint32_t size);
+ static SkAlphaType ConvertToSkAlphaType(AlphaType alphaType);
+ static AlphaType ConvertToAlphaType(SkAlphaType at);
+ static void WriteBigData(MessageParcel *p, const void* data, size_t size, bool isMutable);
+ static PixelMap *CreateSkShellPixelMap(SkBitmap &skBitmap,
+ void *context = nullptr,
+ PixelFormat pixelFormat = PixelFormat::UNKNOWN,
+ ColorSpace colorSpace = ColorSpace::SRGB,
+ bool copy = false);
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // IMAGE_BITMAP_CONVERTER_H
diff --git a/adapter/frameworks/bitmapconverter/native/src/bitmap_wrapper.cpp b/adapter/frameworks/bitmapconverter/native/src/bitmap_wrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b04377b45450af7000030baa326066b95562b72c
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/src/bitmap_wrapper.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2015 The Android Open Source Project
+ * 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 "bitmap_wrapper.h"
+
+namespace android {
+void BitmapWrapper::freePixels()
+{
+ if (!valid()) {
+ ALOGE("BitmapWrapper freePixels already done, so we do nothing");
+ return;
+ }
+ ALOGE("BitmapWrapper freePixels");
+}
+
+bool BitmapWrapper::valid() const
+{
+ return mBitmap != nullptr;
+}
+
+android::Bitmap &BitmapWrapper::bitmap()
+{
+ assertValid();
+ return *mBitmap;
+}
+
+void BitmapWrapper::assertValid() const
+{
+ LOG_ALWAYS_FATAL_IF(!valid(), "Error, cannot access an invalid/free'd bitmap here!");
+}
+
+void BitmapWrapper::getSkBitmap(SkBitmap *outBitmap) const
+{
+ assertValid();
+ mBitmap->getSkBitmap(outBitmap);
+}
+
+bool BitmapWrapper::hasHardwareMipMap()
+{
+ if (mBitmap) {
+ return mBitmap->hasHardwareMipMap();
+ }
+ return mHasHardwareMipMap;
+}
+
+void BitmapWrapper::setHasHardwareMipMap(bool hasMipMap)
+{
+ assertValid();
+ mBitmap->setHasHardwareMipMap(hasMipMap);
+}
+
+void BitmapWrapper::setAlphaType(SkAlphaType alphaType)
+{
+ assertValid();
+ mBitmap->setAlphaType(alphaType);
+}
+
+const SkImageInfo &BitmapWrapper::info()
+{
+ if (mBitmap) {
+ return mBitmap->info();
+ }
+ return mInfo;
+}
+
+size_t BitmapWrapper::getAllocationByteCount() const
+{
+ if (mBitmap) {
+ return mBitmap->getAllocationByteCount();
+ }
+ return mAllocationSize;
+}
+
+size_t BitmapWrapper::rowBytes() const
+{
+ if (mBitmap) {
+ return mBitmap->rowBytes();
+ }
+ return mRowBytes;
+}
+
+uint32_t BitmapWrapper::getGenerationID() const
+{
+ if (mBitmap) {
+ return mBitmap->getGenerationID();
+ }
+ return mGenerationId;
+}
+
+bool BitmapWrapper::isHardware()
+{
+ if (mBitmap) {
+ return mBitmap->isHardware();
+ }
+ return mIsHardware;
+}
+} // namespace android
\ No newline at end of file
diff --git a/adapter/frameworks/bitmapconverter/native/src/image_bitmap_converter.cpp b/adapter/frameworks/bitmapconverter/native/src/image_bitmap_converter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2b2a3b5602d308a5e97ff05f3249c5239d043465
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/src/image_bitmap_converter.cpp
@@ -0,0 +1,430 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2015 The Android Open Source Project
+ * 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 "image_bitmap_converter.h"
+#include "SkBitmap.h"
+#include "SkImageInfo.h"
+
+#include "media_errors.h"
+#if defined(_WIN32) || defined(_APPLE)
+#include
+#else
+#include
+#include
+#include "ashmem.h"
+#include "securec.h"
+#endif
+
+namespace OHOS {
+namespace Media {
+using namespace OHOS::HiviewDFX;
+
+static constexpr uint32_t G_MAX_COLOR_SPACE_SERIALIZED_BYTES = 80;
+
+enum {
+ RAW_INPLACE = 0,
+ RAW_ASHMEM_IMMUTABLE = 1,
+ RAW_ASHMEM_MUTABLE = 2,
+};
+
+SkColorType ImageBitmapConverter::GetColorType(PixelFormat pixelFormat)
+{
+ SkColorType colorType = kUnknown_SkColorType;
+ switch (pixelFormat) {
+ case PixelFormat::ALPHA_8: {
+ colorType = kAlpha_8_SkColorType;
+ break;
+ }
+ case PixelFormat::RGB_565: {
+ colorType = kRGB_565_SkColorType;
+ break;
+ }
+ case PixelFormat::RGBA_F16: {
+ colorType = kRGBA_F16_SkColorType;
+ break;
+ }
+ case PixelFormat::RGBA_8888:
+ case PixelFormat::BGRA_8888: {
+ colorType = kN32_SkColorType;
+ break;
+ }
+ default: {
+ HiLog::Error(LABEL, "convert from pixel format:%{public}d to color type failed.",
+ static_cast(pixelFormat));
+ break;
+ }
+ }
+
+ return colorType;
+}
+
+SkAlphaType ImageBitmapConverter::ConvertToSkAlphaType(AlphaType alphaType)
+{
+ SkAlphaType skAlphaType = kUnknown_SkAlphaType;
+ switch (alphaType) {
+ case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE: {
+ skAlphaType = kOpaque_SkAlphaType;
+ break;
+ }
+ case AlphaType::IMAGE_ALPHA_TYPE_PREMUL: {
+ skAlphaType = kPremul_SkAlphaType;
+ break;
+ }
+ case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL: {
+ skAlphaType = kUnpremul_SkAlphaType;
+ break;
+ }
+ default: {
+ HiLog::Error(LABEL, "unknown alpha type:%{public}d.", static_cast(alphaType));
+ break;
+ }
+ }
+ return skAlphaType;
+}
+
+void ImageBitmapConverter::FreeBitmap(void *addr, void *context)
+{
+ // free bitmap do nothing, the bitmap malloc data will be released by pixelmap destruct function.
+ HiLog::Debug(LABEL, "free bitmap.");
+ return;
+}
+
+android::BitmapWrapper *ImageBitmapConverter::CreateShadowBitmap(PixelMap *pixelMap)
+{
+ if (pixelMap == nullptr) {
+ HiLog::Error(LABEL, "create shadow bitmap error, input parameter is null.");
+ return nullptr;
+ }
+ uint8_t *base = const_cast(pixelMap->GetPixels());
+ if (base == nullptr) {
+ HiLog::Error(LABEL, "create shadow bitmap error, pixel addr is null.");
+ return nullptr;
+ }
+ int32_t width = pixelMap->GetWidth();
+ int32_t height = pixelMap->GetHeight();
+ int32_t rowBytes = pixelMap->GetRowBytes();
+ PixelFormat pixelFormat = pixelMap->GetPixelFormat();
+ SkColorType colorType = GetColorType(pixelFormat);
+ AlphaType alphaType = pixelMap->GetAlphaType();
+ SkAlphaType skAlphaType = ConvertToSkAlphaType(alphaType);
+ SkImageInfo skImageInfo = SkImageInfo::Make(width, height, colorType, skAlphaType, SkColorSpace::MakeSRGB());
+ sk_sp bitmap = nullptr;
+ AllocatorType allocType = pixelMap->GetAllocatorType();
+ if (allocType == AllocatorType::SHARE_MEM_ALLOC) {
+ int32_t *fd = static_cast(pixelMap->GetFd());
+ if (fd == nullptr || *fd < 0) {
+ HiLog::Error(LABEL, "CreateShadowBitmap fd is invalid.");
+ return nullptr;
+ }
+ SkBitmap skBitmap;
+ if (!skBitmap.setInfo((skImageInfo), rowBytes)) {
+ HiLog::Error(LABEL, "CreateShadowBitmap, setInfo failed!");
+ return nullptr;
+ }
+ size_t bitmapSize = skBitmap.computeByteSize();
+ int32_t dupFd = fcntl(*fd, F_DUPFD_CLOEXEC, 0);
+ if (dupFd < 0) {
+ HiLog::Error(LABEL, "CreateShadowBitmap, dupFd < 0.");
+ return nullptr;
+ }
+ bitmap = android::Bitmap::createFrom(skImageInfo, rowBytes, dupFd, nullptr, bitmapSize, false);
+ if (bitmap == nullptr) {
+ HiLog::Error(LABEL, "CreateShadowBitmap malloc bitmap createFrom failed.");
+ ::close(dupFd);
+ return nullptr;
+ }
+ } else {
+ SkPixelRef *skPixelRef = new (std::nothrow) SkPixelRef(width, height, base, rowBytes);
+ if (skPixelRef == nullptr) {
+ HiLog::Error(LABEL, "skPixelRef is nullptr.");
+ return nullptr;
+ }
+ bitmap = android::Bitmap::createFrom(skImageInfo, *skPixelRef);
+ if (bitmap.get() == nullptr) {
+ HiLog::Error(LABEL, "malloc shadow bitmap error.");
+ delete skPixelRef;
+ return nullptr;
+ }
+ }
+ android::BitmapWrapper *bitmapWrapper = new (std::nothrow) android::BitmapWrapper(bitmap.get());
+ if (bitmapWrapper == nullptr) {
+ HiLog::Error(LABEL, "malloc shadow bitmap wrapper error.");
+ return nullptr;
+ }
+ (void)bitmap.release();
+ return bitmapWrapper;
+}
+
+PixelFormat ImageBitmapConverter::GetPixelFormat(SkColorType colorType)
+{
+ PixelFormat pixelFormat = PixelFormat::UNKNOWN;
+ switch (colorType) {
+ case kAlpha_8_SkColorType: {
+ pixelFormat = PixelFormat::ALPHA_8;
+ break;
+ }
+ case kRGB_565_SkColorType: {
+ pixelFormat = PixelFormat::RGB_565;
+ break;
+ }
+ case kRGBA_F16_SkColorType: {
+ pixelFormat = PixelFormat::RGBA_F16;
+ break;
+ }
+ case kRGBA_8888_SkColorType: {
+ pixelFormat = PixelFormat::RGBA_8888;
+ break;
+ }
+ case kBGRA_8888_SkColorType: {
+ pixelFormat = PixelFormat::BGRA_8888;
+ break;
+ }
+ default: {
+ HiLog::Error(LABEL, "convert from color type:%{public}d to pixel format failed.",
+ static_cast(colorType));
+ break;
+ }
+ }
+ return pixelFormat;
+}
+
+AlphaType ImageBitmapConverter::ConvertToAlphaType(SkAlphaType at)
+{
+ AlphaType alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
+ switch (at) {
+ case kOpaque_SkAlphaType: {
+ alphaType = AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
+ break;
+ }
+ case kPremul_SkAlphaType: {
+ alphaType = AlphaType::IMAGE_ALPHA_TYPE_PREMUL;
+ break;
+ }
+ case kUnpremul_SkAlphaType: {
+ alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
+ break;
+ }
+ default: {
+ HiLog::Error(LABEL, "unknown skia alpha type:%{public}d.", static_cast(at));
+ break;
+ }
+ }
+ return alphaType;
+}
+
+void ImageBitmapConverter::FreePixelMapFunc(void *addr, void *context, uint32_t size)
+{
+ android::BitmapWrapper *bitmap = static_cast(context);
+ if (bitmap != nullptr) {
+ bitmap->freePixels();
+ }
+}
+
+PixelMap *ImageBitmapConverter::CreateShellPixelMap(android::BitmapWrapper *bitmapWrapper)
+{
+ if (bitmapWrapper == nullptr) {
+ HiLog::Error(LABEL, "create shell pixel map error, input parameter is null.");
+ return nullptr;
+ }
+ SkBitmap skBitmap;
+ bitmapWrapper->getSkBitmap(&skBitmap);
+ return CreateSkShellPixelMap(skBitmap, bitmapWrapper);
+}
+
+void ImageBitmapConverter::PixelMapWriteToParcel(PixelMap *pixelMap, int density, MessageParcel *p)
+{
+#ifndef _WIN32
+ android::BitmapWrapper *bitmapWrapper = ImageBitmapConverter::CreateShadowBitmap(pixelMap);
+ SkBitmap bitmap;
+ bitmapWrapper->getSkBitmap(&bitmap);
+
+ bool isMutable = pixelMap->IsEditable();
+ p->WriteInt32(isMutable);
+ p->WriteInt32(bitmap.colorType());
+ p->WriteInt32(bitmap.alphaType());
+ SkColorSpace* colorSpace = bitmap.colorSpace();
+ if (colorSpace != nullptr) {
+ sk_sp data = colorSpace->serialize();
+ size_t size = data->size();
+ p->WriteUint32(size);
+ if (size > 0) {
+ if (size > G_MAX_COLOR_SPACE_SERIALIZED_BYTES) {
+ HiLog::Error(LABEL, "Serialized SkColorSpace is larger than expected, ret:%{public}zu.", size);
+ }
+ p->WriteBuffer(data->data(), size);
+ }
+ } else {
+ p->WriteUint32(0);
+ }
+ p->WriteInt32(bitmap.width());
+ p->WriteInt32(bitmap.height());
+ p->WriteInt32(bitmap.rowBytes());
+ p->WriteInt32(density);
+
+ // Transfer the underlying ashmem region if we have one and it's immutable.
+ android::status_t status;
+ int fd = bitmapWrapper->bitmap().getAshmemFd();
+ if (fd >= 0 && !isMutable) {
+ status = p->WriteFileDescriptor(fd);
+ if (status) {
+ HiLog::Error(LABEL, "Could not write file descriptor.");
+ return;
+ }
+ ::close(fd);
+ return;
+ }
+
+ size_t size = bitmap.computeByteSize();
+ const void* pSrc = bitmap.getPixels();
+ if (pSrc == NULL) {
+ if (size == 0) {
+ HiLog::Error(LABEL, "malloc failed, size %{public}zu.", size);
+ return;
+ }
+ void* data = malloc(size);
+ if (data == nullptr) {
+ HiLog::Error(LABEL, "malloc failed, size %{public}zu.", size);
+ return;
+ }
+ if (memset_s(data, size, 0, size) != EOK) {
+ HiLog::Error(LABEL, "memset failed");
+ free(data);
+ return;
+ }
+ WriteBigData(p, data, size, isMutable);
+ free(data);
+ } else {
+ WriteBigData(p, pSrc, size, isMutable);
+ }
+#endif
+ return;
+}
+
+#ifndef _WIN32
+void ImageBitmapConverter::WriteBigData(MessageParcel *p, const void* data, size_t size, bool isMutable)
+{
+ HiLog::Debug(LABEL, "WriteBigData size:[%{public}lld] isMutable:[%{public}d]", (long long)size, isMutable);
+ if (size < SIZE_LIMIT) {
+ p->WriteInt32(RAW_INPLACE);
+ p->WriteBuffer(data, size);
+ return;
+ }
+ int fd = AshmemCreate("Parcel RawData", size);
+ if (fd < 0) {
+ return;
+ }
+ int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
+ if (result < 0) {
+ ::close(fd);
+ return;
+ }
+ void* ptr = ::mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ ::close(fd);
+ return;
+ }
+ if (isMutable) {
+ p->WriteInt32(RAW_ASHMEM_MUTABLE);
+ } else {
+ result = AshmemSetProt(fd, PROT_READ);
+ if (result < 0) {
+ ::munmap(ptr, size);
+ ::close(fd);
+ return;
+ }
+ p->WriteInt32(RAW_ASHMEM_IMMUTABLE);
+ }
+ if (!p->WriteFileDescriptor(fd)) {
+ ::munmap(ptr, size);
+ ::close(fd);
+ return;
+ }
+ if (memcpy_s(ptr, size, data, size) != EOK) {
+ ::munmap(ptr, size);
+ ::close(fd);
+ return;
+ }
+ ::munmap(ptr, size);
+ ::close(fd);
+ return;
+}
+#endif
+PixelMap *ImageBitmapConverter::CreateSkShellPixelMap(SkBitmap &skBitmap, void *context, PixelFormat pixelFormat,
+ ColorSpace colorSpace, bool copy)
+{
+ void *base = skBitmap.getPixels();
+ if (base == nullptr) {
+ HiLog::Error(LABEL, "create skbitmap shell pixel map error, bitmap addr is null.");
+ return nullptr;
+ }
+ int32_t width = skBitmap.width();
+ int32_t height = skBitmap.height();
+ SkColorType colorType = skBitmap.colorType();
+ SkAlphaType skAlphaType = skBitmap.alphaType();
+ size_t byteCount = skBitmap.rowBytes() * height;
+ PixelMap *pixelMap = new (std::nothrow) PixelMap();
+ if (pixelMap == nullptr) {
+ HiLog::Error(LABEL, "malloc skbitmap shell pixel map error.");
+ return nullptr;
+ }
+ ImageInfo info;
+ info.size.width = width;
+ info.size.height = height;
+ info.pixelFormat = (pixelFormat == PixelFormat::UNKNOWN ? GetPixelFormat(colorType) : pixelFormat);
+ info.alphaType = ConvertToAlphaType(skAlphaType);
+ info.colorSpace = colorSpace;
+ uint32_t ret = pixelMap->SetImageInfo(info);
+ if (ret != SUCCESS) {
+ delete pixelMap;
+ HiLog::Error(LABEL, "skbitmap pixel map set image info failed, ret:%{public}u.", ret);
+ return nullptr;
+ }
+ if (copy) {
+ void *dstPixels = malloc(byteCount);
+ if (dstPixels == nullptr) {
+ HiLog::Error(LABEL, "allocate memory byteCount %{public}zu fail", byteCount);
+ return nullptr;
+ }
+ if (memcpy_s(dstPixels, byteCount, base, byteCount) != EOK) {
+ free(dstPixels);
+ return nullptr;
+ }
+ skBitmap.reset();
+ pixelMap->SetPixelsAddr(dstPixels, nullptr, byteCount, AllocatorType::HEAP_ALLOC, nullptr);
+ } else {
+ pixelMap->SetPixelsAddr(base, context, byteCount, AllocatorType::CUSTOM_ALLOC, FreePixelMapFunc);
+ }
+ return pixelMap;
+}
+
+PixelMap *ImageBitmapConverter::createFromAlpha(PixelMap *pixelMapSrc)
+{
+ if (pixelMapSrc) {
+ SkBitmap src;
+ SkBitmap dst;
+ CreateShadowBitmap(pixelMapSrc)->getSkBitmap(&src);
+ if (!src.extractAlpha(&dst) || (dst.getPixels() == nullptr && src.getPixels() != nullptr)) {
+ HiLog::Error(LABEL, "failed to allocate pixels for alpha");
+ return nullptr;
+ }
+ return CreateSkShellPixelMap(dst, nullptr, PixelFormat::ALPHA_8, ColorSpace::SRGB, true);
+ } else {
+ HiLog::Error(LABEL, "input PixelMap is null, unable to get alpha from a null PixelMap");
+ }
+ return nullptr;
+}
+} // namespace Media
+} // namespace OHOS
diff --git a/adapter/frameworks/bitmapconverter/native/src/image_native_interface_utils.cpp b/adapter/frameworks/bitmapconverter/native/src/image_native_interface_utils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5586c78d559d8f9fa4d7b0d18f5f67d6a932056
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/src/image_native_interface_utils.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2015 The Android Open Source Project
+ * 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 "hilog/log.h"
+#include "image_bitmap_converter.h"
+#include "jkit_utils.h"
+#include "log_tags.h"
+#include "media_errors.h"
+#include "pixel_map.h"
+#include "pixel_map_manager.h"
+
+using namespace OHOS::HiviewDFX;
+using namespace OHOS::Media;
+
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "Image_Native_Interface_Utils"
+};
+
+namespace OHOS {
+namespace Media {
+PixelMap *GetNativePixelMap(JNIEnv *env, jobject pixelMapObj)
+{
+ if (pixelMapObj == nullptr) {
+ HiLog::Error(LABEL, "GetNativePixelMapPtr, pixelMap object is null.");
+ return nullptr;
+ }
+ jclass pixelMapClazz = env->GetObjectClass(pixelMapObj);
+ if (pixelMapClazz == nullptr) {
+ HiLog::Error(LABEL, "GetNativePixelMapPtr, PixelMap class not found.");
+ return nullptr;
+ }
+ jfieldID pixelMapFileId = env->GetFieldID(pixelMapClazz, "nativeImagePixelMap", "J");
+ env->DeleteLocalRef(pixelMapClazz);
+ if (pixelMapFileId == nullptr) {
+ HiLog::Error(LABEL, "GetNativePixelMapPtr get nativeImagePixelMap error.");
+ return nullptr;
+ }
+ jlong pixelMapPtr = env->GetLongField(pixelMapObj, pixelMapFileId);
+ PixelMapManager *pixelMapManager = reinterpret_cast(pixelMapPtr);
+ if (pixelMapManager == nullptr || pixelMapManager->Invalid()) {
+ HiLog::Error(LABEL, "GetNativeBitmap pixelMap is null.");
+ return nullptr;
+ }
+ return &(pixelMapManager->GetPixelMap());
+}
+
+jobject GetNativeBitmap(JNIEnv *env, jobject pixelMapObj)
+{
+ if (pixelMapObj == nullptr) {
+ HiLog::Error(LABEL, "GetNativeBitmap, pixelMap object is null.");
+ return nullptr;
+ }
+ PixelMap *pixelMap = GetNativePixelMap(env, pixelMapObj);
+ if (pixelMap == nullptr) {
+ HiLog::Error(LABEL, "GetNativeBitmap pixelMap is null.");
+ return nullptr;
+ }
+
+ jclass bitmapClazz = env->FindClass("android/graphics/Bitmap");
+ if (bitmapClazz == nullptr) {
+ HiLog::Error(LABEL, "GetNativeBitmap: find android Bitmap class fail, bitmapClazz is null.");
+ return nullptr;
+ }
+
+ jmethodID bitmapConstructMethodId =
+ env->GetMethodID(bitmapClazz, "", "(JIIIZ[BLandroid/graphics/NinePatch$InsetStruct;Z)V");
+ if (bitmapConstructMethodId == nullptr) {
+ HiLog::Error(LABEL,
+ "GetNativeBitmap: find android Bitmap construct method fail, bitmapConstructMethodId is null.");
+ env->DeleteLocalRef(bitmapClazz);
+ return nullptr;
+ }
+
+ android::BitmapWrapper *bitmapWrapper = ImageBitmapConverter::CreateShadowBitmap(pixelMap);
+ if (bitmapWrapper == nullptr) {
+ HiLog::Error(LABEL, "GetNativeBitmap bitmap is null.");
+ env->DeleteLocalRef(bitmapClazz);
+ return nullptr;
+ }
+
+ bool heapAlloc = pixelMap->GetAllocatorType() == AllocatorType::HEAP_ALLOC;
+ jobject bitmapObj = env->NewObject(bitmapClazz, bitmapConstructMethodId, reinterpret_cast(bitmapWrapper),
+ bitmapWrapper->bitmap().width(), bitmapWrapper->bitmap().height(), -1, true,
+ nullptr, nullptr, heapAlloc);
+ env->DeleteLocalRef(bitmapClazz);
+
+ return bitmapObj;
+}
+
+jobject GetShellPixelMap(JNIEnv *env, jobject bitmapObj)
+{
+ if (bitmapObj == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap, pixelMap object is null.");
+ return nullptr;
+ }
+ jclass bitmapClazz = env->GetObjectClass(bitmapObj);
+ if (bitmapClazz == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap, Bitmap class not found.");
+ return nullptr;
+ }
+ jfieldID bitmapWrapperFileId = env->GetFieldID(bitmapClazz, "mNativePtr", "J");
+ env->DeleteLocalRef(bitmapClazz);
+ if (bitmapWrapperFileId == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap get mNativeBitmap error.");
+ return nullptr;
+ }
+ jlong bitmapWrapperPtr = env->GetLongField(bitmapObj, bitmapWrapperFileId);
+ android::BitmapWrapper *bitmapWrapper = reinterpret_cast(bitmapWrapperPtr);
+ if (bitmapWrapper == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap bitmapWrapper is null.");
+ return nullptr;
+ }
+
+ jclass pixelMapClazz = env->FindClass("ohos/media/image/PixelMap");
+ if (pixelMapClazz == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap: find PixelMap class fail, pixelMapClazz is null.");
+ return nullptr;
+ }
+
+ jmethodID pixelMapConstructMethodId = env->GetMethodID(pixelMapClazz, "", "(JJJ)V");
+ if (pixelMapConstructMethodId == nullptr) {
+ HiLog::Error(LABEL,
+ "GetShellPixelMap: find PixelMap construct method fail, pixelMapConstructMethodId is null.");
+ env->DeleteLocalRef(pixelMapClazz);
+ return nullptr;
+ }
+
+ PixelMap *pixelMap = ImageBitmapConverter::CreateShellPixelMap(bitmapWrapper);
+ if (pixelMap == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap pixelMap is null.");
+ env->DeleteLocalRef(pixelMapClazz);
+ return nullptr;
+ }
+ PixelMapManager *pixelMapManager = new (std::nothrow) PixelMapManager(pixelMap);
+ if (pixelMapManager == nullptr) {
+ HiLog::Error(LABEL, "new pixelMapManager is null.");
+ env->DeleteLocalRef(pixelMapClazz);
+ return nullptr;
+ }
+ jobject globalBitmapObj = env->NewGlobalRef(bitmapObj);
+ jobject pixelMapObj =
+ env->NewObject(pixelMapClazz, pixelMapConstructMethodId, reinterpret_cast(pixelMapManager),
+ static_cast(pixelMap->GetByteCount()), reinterpret_cast(globalBitmapObj));
+ env->DeleteLocalRef(pixelMapClazz);
+ return pixelMapObj;
+}
+
+void PixelMapWriteToParcel(JNIEnv* env, jobject pixelMapObj, jobject zParcel)
+{
+ if (zParcel == NULL) {
+ HiLog::Error(LABEL, "writeToParcel null parcel.");
+ return;
+ }
+ jclass zParcelClazz = env->GetObjectClass(zParcel);
+ if (zParcelClazz == NULL) {
+ HiLog::Error(LABEL, "writeToParcel null zParcelClazz.");
+ return;
+ }
+ jfieldID zNativeHandleField = env->GetFieldID(zParcelClazz, "nativeHandle", "J");
+ env->DeleteLocalRef(zParcelClazz);
+ if (zNativeHandleField == nullptr) {
+ HiLog::Error(LABEL, "zNativeHandleField is invalid");
+ return;
+ }
+ jlong zParcelNative = env->GetLongField(zParcel, zNativeHandleField);
+ auto parcelZ = reinterpret_cast(zParcelNative);
+ HiLog::Debug(LABEL, "PixelMapWriteToParcel zParcel Ptr=%p", parcelZ);
+
+ if (parcelZ == nullptr) {
+ HiLog::Debug(LABEL, "Failed to get Z native Parcel");
+ return;
+ }
+ if (pixelMapObj == nullptr) {
+ HiLog::Error(LABEL, "nativeWriteToParcel, pixelMap object is null.");
+ return;
+ }
+ jclass pixelMapClazz = env->FindClass("ohos/media/image/PixelMap");
+ if (pixelMapClazz == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap: find PixelMap class fail, pixelMapClazz is null.");
+ return;
+ }
+ jmethodID pixelMapGetDensityMethodId = env->GetMethodID(pixelMapClazz, "getBaseDensity", "()I");
+ if (pixelMapGetDensityMethodId == nullptr) {
+ HiLog::Error(LABEL, "GetShellPixelMap: pixelMapGetDensityMethodId is null.");
+ env->DeleteLocalRef(pixelMapClazz);
+ return;
+ }
+ env->DeleteLocalRef(pixelMapClazz);
+ jint density = env->CallIntMethod(pixelMapObj, pixelMapGetDensityMethodId);
+ PixelMap *pixelMap = GetNativePixelMap(env, pixelMapObj);
+ if (pixelMap == nullptr) {
+ HiLog::Error(LABEL, "nativeWriteToParcel pixelMap is null.");
+ return;
+ }
+ ImageBitmapConverter::PixelMapWriteToParcel(pixelMap, density, parcelZ);
+}
+} // namespace Media
+} // namespace OHOS
diff --git a/adapter/frameworks/bitmapconverter/native/src/ohos_image_ImageDoubleFwConverter.cpp b/adapter/frameworks/bitmapconverter/native/src/ohos_image_ImageDoubleFwConverter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ecf4faf0c52d2f9c9aba25076b365a127ce4ccf
--- /dev/null
+++ b/adapter/frameworks/bitmapconverter/native/src/ohos_image_ImageDoubleFwConverter.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2015 The Android Open Source Project
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include
+#include "hilog/log.h"
+#include "image_native_interface_utils.h"
+#include "jkit_utils.h"
+#include "log_tags.h"
+#include "media_errors.h"
+
+using namespace OHOS::HiviewDFX;
+using namespace OHOS::Media;
+
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "ImageDoubleFwConverter_JNI"
+};
+
+jobject ohos_media_image_inner_ImageDoubleFwConverter_nativeCreateBitmap(JNIEnv *env, jobject thiz,
+ jobject pixelMapObj)
+{
+ jobject bitmap = GetNativeBitmap(env, pixelMapObj);
+ if (bitmap == nullptr) {
+ HiLog::Error(LABEL, "nativeCreateBitmap GetNativeBitmap fail");
+ return nullptr;
+ }
+
+ return bitmap;
+}
+
+jobject ohos_media_image_inner_ImageDoubleFwConverter_nativeCreatePixelMap(JNIEnv *env, jobject thiz,
+ jobject bitmapObj)
+{
+ jobject pixelMapObj = GetShellPixelMap(env, bitmapObj);
+ if (pixelMapObj == nullptr) {
+ HiLog::Error(LABEL, "nativeCreatePixelMap GetShellPixelMap fail");
+ return nullptr;
+ }
+
+ return pixelMapObj;
+}
+
+void ohos_media_image_inner_ImageDoubleFwConverter_nativeWriteToParcel(JNIEnv *env, jobject thiz,
+ jobject pixelMapObj,
+ jobject parcel)
+{
+ PixelMapWriteToParcel(env, pixelMapObj, parcel);
+ return;
+}
+
+static const JNINativeMethod METHODS[] = {
+ { "nativeCreateBitmap", "(Lohos/media/image/PixelMap;)Landroid/graphics/Bitmap;",
+ reinterpret_cast(ohos_media_image_inner_ImageDoubleFwConverter_nativeCreateBitmap) },
+ { "nativeCreatePixelMap", "(Landroid/graphics/Bitmap;)Lohos/media/image/PixelMap;",
+ reinterpret_cast(ohos_media_image_inner_ImageDoubleFwConverter_nativeCreatePixelMap) },
+ { "nativeWriteToParcel", "(Lohos/media/image/PixelMap;Lohos/utils/Parcel;)V",
+ reinterpret_cast(ohos_media_image_inner_ImageDoubleFwConverter_nativeWriteToParcel) }
+};
+
+jint JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ HiLog::Debug(LABEL, "JNI_OnLoad begin");
+ JNIEnv *env = nullptr;
+ if (vm->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_4) != JNI_OK) {
+ HiLog::Error(LABEL, "JNI_OnLoad: GetEnv failed");
+ return ERROR;
+ }
+ int ret = JkitRegisterNativeMethods(env, "ohos/media/image/inner/ImageDoubleFwConverter", METHODS,
+ ARRCOUNT(METHODS));
+ if (ret == JNI_ERR) {
+ HiLog::Error(LABEL, "JkitRegisterNativeMethods failed, ret=%{public}d", ret);
+ return ERROR;
+ }
+ Jkit::nativeInit(vm);
+ HiLog::Debug(LABEL, "JNI_OnLoad end");
+ return JNI_VERSION_1_4;
+}
diff --git a/adapter/frameworks/exif/BUILD.gn b/adapter/frameworks/exif/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..9354fa78f35ca2598f0cc25fc83e1b7ab0f7479f
--- /dev/null
+++ b/adapter/frameworks/exif/BUILD.gn
@@ -0,0 +1,40 @@
+# Copyright (C) 2021 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("//build/config/ohos/rules.gni")
+
+java_library("image_exifadapter_java") {
+ java_files = [ "src/ohos/media/image/exifadapter/ExifAdapter.java" ]
+
+ classpath_deps =
+ [ "//foundation/multimedia/utils/java:multimedia_utils_java" ]
+
+ external_deps = [ "utils:utils_java" ]
+ part_name = "multimedia_image"
+}
+
+ohos_maple_java("image_exifadapter_maple_java") {
+ deps = [
+ ":image_exifadapter_java",
+ "//foundation/multimedia/utils/java:multimedia_utils_maple_java",
+ ]
+
+ aosp_deps = [ "maple:framework" ]
+
+ external_deps = [
+ "hilog:hilog_maple_java",
+ "utils:utils_maple_java",
+ ]
+
+ subsystem_name = "multimedia"
+}
diff --git a/adapter/frameworks/exif/src/ohos/media/image/exifadapter/ExifAdapter.java b/adapter/frameworks/exif/src/ohos/media/image/exifadapter/ExifAdapter.java
new file mode 100644
index 0000000000000000000000000000000000000000..511dac98b42e171b99e492e3aa19a84ac40f7a58
--- /dev/null
+++ b/adapter/frameworks/exif/src/ohos/media/image/exifadapter/ExifAdapter.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2007 The Android Open Source Project
+ * 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.
+ */
+
+package ohos.media.image.exifadapter;
+
+import android.media.ExifInterface;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * exif adapter for ImageSource.
+ *
+ * @since 3
+ */
+public class ExifAdapter {
+ private final ExifInterface exifInterface;
+
+ /**
+ * Instantiates a new Exif adapter.
+ *
+ * @param pathName the path name
+ * @throws IOException the io exception
+ * @since 3
+ */
+ public ExifAdapter(String pathName) throws IOException {
+ exifInterface = new ExifInterface(pathName);
+ }
+
+ /**
+ * Instantiates a new Exif adapter.
+ *
+ * @param inputStream the input stream
+ * @throws IOException the io exception
+ * @since 3
+ */
+ public ExifAdapter(InputStream inputStream) throws IOException {
+ exifInterface = new ExifInterface(inputStream);
+ }
+
+ /**
+ * Instantiates a new Exif adapter.
+ *
+ * @param data the data
+ * @param offset the offset
+ * @param length the length
+ * @throws IOException the io exception
+ * @since 3
+ */
+ public ExifAdapter(byte[] data, int offset, int length) throws IOException {
+ exifInterface = new ExifInterface(new ByteArrayInputStream(data, offset, length));
+ }
+
+ /**
+ * Instantiates a new Exif adapter.
+ *
+ * @param file the input file
+ * @throws IOException the io exception
+ * @since 3
+ */
+ public ExifAdapter(File file) throws IOException {
+ exifInterface = new ExifInterface(file);
+ }
+
+ /**
+ * Instantiates a new Exif adapter.
+ *
+ * @param fd the input fd
+ * @throws IOException the io exception
+ * @since 3
+ */
+ public ExifAdapter(FileDescriptor fd) throws IOException {
+ exifInterface = new ExifInterface(fd);
+ }
+
+ /**
+ * Gets image property.
+ *
+ * @param key the key
+ * @return the image property
+ * @since 3
+ */
+ public String getImagePropertyString(String key) {
+ return exifInterface.getAttribute(key);
+ }
+
+ /**
+ * Gets image property int.
+ *
+ * @param key the key
+ * @param defaultValue the default value
+ * @return the image property int
+ * @since 3
+ */
+ public int getImagePropertyInt(String key, int defaultValue) {
+ return exifInterface.getAttributeInt(key, defaultValue);
+ }
+
+ /**
+ * Get thumbnail bytes byte.
+ *
+ * @return the byte
+ * @since 3
+ */
+ public byte[] getThumbnailBytes() {
+ return exifInterface.getThumbnailBytes();
+ }
+
+ /**
+ * Get thumbnail byte.
+ *
+ * @return the byte
+ * @since 3
+ */
+ public byte[] getThumbnail() {
+ return exifInterface.getThumbnail();
+ }
+
+ /**
+ * Get thumbnail offset and length.
+ *
+ * @return two-element array, the offset in the first value, and length in the
+ * second, or {@code null} if no thumbnail was found or the thumbnail
+ * strips are not placed consecutively.
+ * @since 6
+ */
+ public long[] getThumbnailRange() {
+ return exifInterface.getThumbnailRange();
+ }
+
+ /**
+ * Gets image property double.
+ *
+ * @param key the key
+ * @param defaultValue the default value
+ * @return the image property double
+ */
+ public double getImagePropertyDouble(String key, double defaultValue) {
+ return exifInterface.getAttributeDouble(key, defaultValue);
+ }
+
+ /**
+ * set image property.
+ *
+ * @param key the property key
+ * @param property value
+ * @since 3
+ */
+ public void setImageProperty(String key, String value) {
+ exifInterface.setAttribute(key, value);
+ }
+
+ /**
+ * Save the setImageProperty property data into the original image file
+ *
+ * @throws IOException the io exception
+ * @since 3
+ */
+ public void saveAttributes() throws IOException {
+ try {
+ exifInterface.saveAttributes();
+ } catch (IOException e) {
+ throw new IOException("only supports JPEG format for changing and saving Exif properties");
+ }
+ }
+}
diff --git a/adapter/frameworks/heifcodec/BUILD.gn_old b/adapter/frameworks/heifcodec/BUILD.gn_old
new file mode 100644
index 0000000000000000000000000000000000000000..0139c0e7a6faa7f65c124968a7114b31108db3db
--- /dev/null
+++ b/adapter/frameworks/heifcodec/BUILD.gn_old
@@ -0,0 +1,52 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+config("heifadapter_public_config") {
+ visibility = [ ":*" ]
+}
+
+ohos_shared_library("heifadapter") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/heifcodec/src/heif_decoder_adapter.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/heifcodec/src/heif_stream_wrapper.cpp",
+ ]
+
+ include_dirs = [
+ "//utils/native/base/include",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include",
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include/image",
+ "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase",
+ "//foundation/multimedia/image_standard/plugins/common/libs/image/libheifplugin/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/adapter/frameworks/heifcodec/include",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ ]
+
+ deps = [
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+ "//utils/native/base:utils",
+ ]
+
+ public_configs = [ ":heifadapter_public_config" ]
+
+# aosp_deps = [ "shared_library:libheif" ]
+
+# external_deps = [ "hilog:libhilog" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/heifcodec/include/heif_decoder_adapter.h b/adapter/frameworks/heifcodec/include/heif_decoder_adapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..c014a1315578cda48f8436fedcd1e7e648b86449
--- /dev/null
+++ b/adapter/frameworks/heifcodec/include/heif_decoder_adapter.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 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 HEIF_DECODER_ADAPTER_H
+#define HEIF_DECODER_ADAPTER_H
+
+#include
+#include "abs_image_decoder.h"
+#include "heif_decoder_interface.h"
+#include "heif_stream_wrapper.h"
+#include "image_plugin_type.h"
+#include "nocopyable.h"
+
+namespace OHOS {
+namespace Media {
+class HeifDecoderAdapter : public ImagePlugin::HeifDecoderInterface {
+public:
+ HeifDecoderAdapter() = default;
+ explicit HeifDecoderAdapter(HeifDecoder *heifDecoder);
+ virtual ~HeifDecoderAdapter() override{};
+ static std::unique_ptr MakeFromStream(ImagePlugin::InputDataStream &stream);
+ virtual uint32_t OnGetPixels(const ImagePlugin::PlSize &dstSize, const uint32_t dstRowBytes,
+ ImagePlugin::DecodeContext &context) override;
+ virtual void SetAllowPartial(const bool isAllowPartialImage) override;
+ virtual void GetHeifSize(ImagePlugin::PlSize &size) override;
+ virtual bool ConversionSupported(const ImagePlugin::PlPixelFormat &plPixelFormat, int32_t &bytesPerPixel) override;
+ uint32_t ReadRows(const uint32_t rowBytes, const uint32_t count, ImagePlugin::DecodeContext &context);
+
+private:
+ DISALLOW_COPY_AND_MOVE(HeifDecoderAdapter);
+ std::unique_ptr heifDecoder_ = nullptr;
+ bool isAllowPartialImage_ = false;
+ static HeifFrameInfo heifFrameInfo_;
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // HEIF_DECODER_ADAPTER_H
\ No newline at end of file
diff --git a/adapter/frameworks/heifcodec/include/heif_stream_wrapper.h b/adapter/frameworks/heifcodec/include/heif_stream_wrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9fb7455ead83da397825112a7630cc7a7760fbd
--- /dev/null
+++ b/adapter/frameworks/heifcodec/include/heif_stream_wrapper.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2017 The Android Open Source Project
+ * 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 HEIF_STREAM_WRAPPER_H
+#define HEIF_STREAM_WRAPPER_H
+
+#include "HeifDecoderAPI.h"
+#include "input_data_stream.h"
+#include "nocopyable.h"
+
+namespace OHOS {
+namespace Media {
+class HeifStreamWrapper : public HeifStream {
+public:
+ HeifStreamWrapper() = default;
+ explicit HeifStreamWrapper(ImagePlugin::InputDataStream *stream);
+ virtual ~HeifStreamWrapper() override{};
+ virtual size_t read(void *buffer, size_t size) override;
+ virtual bool rewind() override;
+ virtual bool seek(size_t position) override;
+ virtual bool hasLength() const override;
+ virtual size_t getLength() const override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(HeifStreamWrapper);
+ ImagePlugin::InputDataStream *inputData_ = nullptr;
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // HEIF_STREAM_WRAPPER_H
\ No newline at end of file
diff --git a/adapter/frameworks/heifcodec/src/heif_decoder_adapter.cpp b/adapter/frameworks/heifcodec/src/heif_decoder_adapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..99e2a1af89b732e14d37c9da103aafd8a75448a5
--- /dev/null
+++ b/adapter/frameworks/heifcodec/src/heif_decoder_adapter.cpp
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2021 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 "heif_decoder_adapter.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "media_errors.h"
+
+namespace OHOS {
+namespace Media {
+using namespace OHOS::HiviewDFX;
+using namespace ImagePlugin;
+
+constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "HeifDecodeAdapter" };
+
+constexpr int32_t PER_BYTES_RGB565 = 2;
+constexpr int32_t PER_BYTES_RGBA = 4;
+constexpr int32_t PER_BYTES_BGRA = 4;
+
+HeifFrameInfo HeifDecoderAdapter::heifFrameInfo_;
+HeifDecoderAdapter::HeifDecoderAdapter(HeifDecoder *heifDecoder) : heifDecoder_(heifDecoder)
+{}
+
+std::unique_ptr HeifDecoderAdapter::MakeFromStream(InputDataStream &stream)
+{
+ std::unique_ptr heifDecoder(createHeifDecoder());
+ if (heifDecoder.get() == nullptr) {
+ HiLog::Error(LABEL, "heif decoder object is null.");
+ return nullptr;
+ }
+
+ HeifStreamWrapper *heifStreamWrapper = new (std::nothrow) HeifStreamWrapper(&stream);
+ if (heifStreamWrapper == nullptr) {
+ HiLog::Error(LABEL, "create heif stream wrapper object failed.");
+ return nullptr;
+ }
+
+ if (!heifDecoder->init(heifStreamWrapper, &heifFrameInfo_)) {
+ HiLog::Error(LABEL, "init heif decoder failed.");
+ delete heifStreamWrapper;
+ return nullptr;
+ }
+
+ HeifDecoderAdapter *heifDecoderAdapter = new (std::nothrow) HeifDecoderAdapter(heifDecoder.release());
+ if (heifDecoderAdapter == nullptr) {
+ HiLog::Error(LABEL, "create heif decoder adapter object failed.");
+ delete heifStreamWrapper;
+ return nullptr;
+ }
+ return std::unique_ptr(heifDecoderAdapter);
+}
+
+uint32_t HeifDecoderAdapter::ReadRows(const uint32_t rowBytes, const uint32_t count, DecodeContext &context)
+{
+ uint8_t *decodeDst = static_cast(context.pixelsBuffer.buffer);
+ for (uint32_t i = 0; i < count; i++) {
+ if (!heifDecoder_->getScanline(decodeDst)) {
+ HiLog::Error(LABEL, "scan line failed, current rows:%{public}u.", i);
+ return i;
+ }
+ decodeDst = (decodeDst + rowBytes);
+ if (decodeDst == nullptr) {
+ HiLog::Error(LABEL, "decodeDst is null, current rows:%{public}u.", i);
+ return i;
+ }
+ }
+ return count;
+}
+
+uint32_t HeifDecoderAdapter::OnGetPixels(const PlSize &dstSize, const uint32_t dstRowBytes, DecodeContext &context)
+{
+ if (context.pixelsBuffer.buffer == nullptr) {
+ HiLog::Error(LABEL, "buffer is null.");
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+
+ HeifFrameInfo heifInfo;
+ bool success = heifDecoder_->decode(&heifInfo);
+ if (!success) {
+ HiLog::Error(LABEL, "heif decode failed.");
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+
+ uint32_t rows = this->ReadRows(dstRowBytes, dstSize.height, context);
+ if (rows < dstSize.height && !isAllowPartialImage_) {
+ HiLog::Error(LABEL, "current rows:%{public}u less than desire height:%{public}u.", rows, dstSize.height);
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+
+ return SUCCESS;
+}
+
+void HeifDecoderAdapter::GetHeifSize(PlSize &size)
+{
+ size.width = heifFrameInfo_.mWidth;
+ size.height = heifFrameInfo_.mHeight;
+}
+
+void HeifDecoderAdapter::SetAllowPartial(const bool isAllowPartialImage)
+{
+ HiLog::Debug(LABEL, "allow image display partial.");
+ isAllowPartialImage_ = isAllowPartialImage;
+}
+
+bool HeifDecoderAdapter::ConversionSupported(const PlPixelFormat &format, int32_t &bytesPerPixel)
+{
+ bool isSetOK = true;
+ switch (format) {
+ case PlPixelFormat::RGBA_8888:
+ isSetOK = heifDecoder_->setOutputColor(kHeifColorFormat_RGBA_8888);
+ bytesPerPixel = PER_BYTES_RGBA;
+ break;
+ case PlPixelFormat::BGRA_8888:
+ isSetOK = heifDecoder_->setOutputColor(kHeifColorFormat_BGRA_8888);
+ bytesPerPixel = PER_BYTES_BGRA;
+ break;
+ case PlPixelFormat::RGB_565:
+ isSetOK = heifDecoder_->setOutputColor(kHeifColorFormat_RGB565);
+ bytesPerPixel = PER_BYTES_RGB565;
+ break;
+ default:
+ isSetOK = heifDecoder_->setOutputColor(kHeifColorFormat_RGBA_8888);
+ bytesPerPixel = PER_BYTES_RGBA;
+ break;
+ }
+ return isSetOK;
+}
+} // namespace Media
+} // namespace OHOS
\ No newline at end of file
diff --git a/adapter/frameworks/heifcodec/src/heif_stream_wrapper.cpp b/adapter/frameworks/heifcodec/src/heif_stream_wrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e1be8aad2fc955ceb822dbfb5630154b90b08a92
--- /dev/null
+++ b/adapter/frameworks/heifcodec/src/heif_stream_wrapper.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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 "heif_stream_wrapper.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace Media {
+using namespace OHOS::HiviewDFX;
+constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "HeifStreamWrapper" };
+
+HeifStreamWrapper::HeifStreamWrapper(ImagePlugin::InputDataStream *stream) : inputData_(stream){};
+size_t HeifStreamWrapper::read(void *buffer, size_t size)
+{
+ if (buffer == nullptr) {
+ HiLog::Error(LABEL, "input buffer is null.");
+ return size;
+ }
+
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputData_->Read(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "read data failed.");
+ return 0;
+ }
+ return readSize;
+}
+
+bool HeifStreamWrapper::rewind()
+{
+ return inputData_->Seek(0);
+}
+
+bool HeifStreamWrapper::seek(size_t position)
+{
+ return inputData_->Seek(position);
+}
+
+bool HeifStreamWrapper::hasLength() const
+{
+ return inputData_->Tell() != inputData_->GetStreamSize();
+}
+
+size_t HeifStreamWrapper::getLength() const
+{
+ return inputData_->GetStreamSize();
+}
+} // namespace Media
+} // namespace OHOS
\ No newline at end of file
diff --git a/adapter/frameworks/hwjpegcodec/.BUILD.gn.swp b/adapter/frameworks/hwjpegcodec/.BUILD.gn.swp
new file mode 100644
index 0000000000000000000000000000000000000000..39681471c5924a3a7a56f9e992861f3bbf6bec8a
Binary files /dev/null and b/adapter/frameworks/hwjpegcodec/.BUILD.gn.swp differ
diff --git a/adapter/frameworks/hwjpegcodec/BUILD.gn_old b/adapter/frameworks/hwjpegcodec/BUILD.gn_old
new file mode 100644
index 0000000000000000000000000000000000000000..f48ba395e739195a3e417e9c77b16709aaa1438f
--- /dev/null
+++ b/adapter/frameworks/hwjpegcodec/BUILD.gn_old
@@ -0,0 +1,55 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+config("hwjpegadapter_public_config") {
+ visibility = [ ":*" ]
+}
+
+ohos_shared_library("hwjpegadapter") {
+ sources = [ "//foundation/multimedia/image_standard/adapter/frameworks/hwjpegcodec/src/hw_jpeg_decompressor_adapter.cpp" ]
+
+ include_dirs = [
+ "//utils/native/base/include",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include",
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include/image",
+ "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libhwjpegplugin/include",
+ "//third_party/libjpeg-turbo",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/adapter/frameworks/hwjpegcodec/include",
+ ]
+
+ deps = [
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+ "//utils/native/base:utils",
+ ]
+
+ public_configs = [ ":hwjpegadapter_public_config" ]
+
+# aosp_deps = [
+# "shared_library:libcutils",
+# "shared_library:libhidlbase",
+# "shared_library:libjpeg",
+# "shared_library:libutils",
+# "shared_library:vendor.huawei.hardware.jpegdec@1.0",
+# ]
+
+# external_deps = [ "hilog:libhilog" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/hwjpegcodec/include/hw_jpeg_decompressor_adapter.h b/adapter/frameworks/hwjpegcodec/include/hw_jpeg_decompressor_adapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..2e34b2c4bc8c0813d494d51bb67fe910dea5fa39
--- /dev/null
+++ b/adapter/frameworks/hwjpegcodec/include/hw_jpeg_decompressor_adapter.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2009 The Android Open Source Project
+ * 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 HW_JPEG_DECOMPRESSOR_ADAPTER_H
+#define HW_JPEG_DECOMPRESSOR_ADAPTER_H
+
+#include
+#include
+#include "abs_image_decoder.h"
+#include "cutils/native_handle.h"
+#include "hilog/log.h"
+#include "hw_jpeg_decompressor_interface.h"
+#include "jerror.h"
+#include "jpeglib.h"
+#include "log_tags.h"
+#include "vendor/huawei/hardware/jpegdec/1.0/IJpegDecode.h"
+
+namespace OHOS {
+namespace Media {
+constexpr int32_t HISI_JPEG_DECODE_OUT_UNKNOWN = -1;
+constexpr int32_t HISI_JPEG_DECODE_OUT_RGB565 = 7;
+constexpr int32_t HISI_JPEG_DECODE_OUT_RGBA8888 = 9;
+constexpr int32_t HISI_JPEG_DECODE_OUT_BGRA8888 = 10;
+
+using ::android::hardware::hidl_vec;
+using vendor::huawei::hardware::jpegdec::V1_0::hwdecode_region_info;
+using vendor::huawei::hardware::jpegdec::V1_0::IJpegDecode;
+using vendor::huawei::hardware::jpegdec::V1_0::jpeg_comp_hidl_info;
+using vendor::huawei::hardware::jpegdec::V1_0::jpeg_decompress_hidl_t;
+using vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error;
+using vendor::huawei::hardware::jpegdec::V1_0::jpeg_huff_hidl_tbl;
+using vendor::huawei::hardware::jpegdec::V1_0::jpeg_quant_hidl_tbl;
+
+// use for message to HAL.
+struct JpegOutInfo : public native_handle {
+ int32_t sharedFd;
+ int32_t outWidth;
+ int32_t outHeight;
+ int32_t byteStride;
+ int32_t size;
+ int32_t alignSize;
+ int32_t outHnd;
+ int32_t colorFormat;
+ uint64_t outBufferAddr;
+};
+
+struct JpegInInfo : public native_handle {
+ int32_t sharedFd;
+ int32_t dataSize;
+ int32_t alignSize;
+ int32_t ionHnd;
+ uint64_t inBufferAddr;
+};
+
+class HwJpegDecompressorAdapter : public ImagePlugin::HwJpegDecompressorInterface {
+public:
+ HwJpegDecompressorAdapter() = default;
+ ~HwJpegDecompressorAdapter() = default;
+ bool LockDevice() override;
+ void UnlockDevice() override;
+ bool CheckHardwareSupport(const jpeg_decompress_struct *cinfo) override;
+ uint8_t *GetInputBuffer(size_t bufferSize) override;
+ bool HardwareDecode(const jpeg_decompress_struct *jpgDinfo, const uint8_t *inputData, size_t bufferSize,
+ ImagePlugin::DecodeContext &context) override;
+ void ReleaseInputBuffer(uint8_t *addr) override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(HwJpegDecompressorAdapter);
+ size_t GetCompressPos(const uint8_t *inBufMapAddr, size_t buffersize);
+ bool GetDecodeInfo(const jpeg_decompress_struct *jpgDinfo, jpeg_decompress_hidl_t *decInfo);
+ bool FillHuffTable(const JHUFF_TBL *inHuffTable, jpeg_huff_hidl_tbl &outHuffTable);
+ bool FillQuantTable(const JQUANT_TBL *inQuantTable, jpeg_quant_hidl_tbl &outQuantTable);
+ bool FillComponentInfo(const jpeg_decompress_struct *jpgDinfo, jpeg_decompress_hidl_t *decInfo);
+ uint8_t *GetOutputBuffer(const jpeg_decompress_struct *cinfo, native_handle_t *&handle);
+ static void ReleaseBuffer(void *addr, void *context, uint32_t size);
+ int32_t ComputeDecodeOutColorFormat(uint32_t colorFormat);
+ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "HwJpegDecompressorAdapter"
+ };
+ android::sp jpegDecode_ = nullptr;
+ native_handle_t *inBufHnd_ = nullptr;
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // HW_JPEG_DECOMPRESSOR_ADAPTER_H
\ No newline at end of file
diff --git a/adapter/frameworks/hwjpegcodec/src/hw_jpeg_decompressor_adapter.cpp b/adapter/frameworks/hwjpegcodec/src/hw_jpeg_decompressor_adapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c805003b4d5c7ef418a30250c8b54a00f68ebbab
--- /dev/null
+++ b/adapter/frameworks/hwjpegcodec/src/hw_jpeg_decompressor_adapter.cpp
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2009 The Android Open Source Project
+ * 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 "hw_jpeg_decompressor_adapter.h"
+
+#include
+#include
+#include "jerror.h"
+#include "media_errors.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace Media {
+using namespace OHOS::HiviewDFX;
+using namespace ImagePlugin;
+using namespace MultimediaPlugin;
+
+constexpr int32_t JPEG_INFO_BITS_LENGTH = 17;
+constexpr int32_t JPEG_INFO_HUFFVAL_LENGTH = 256;
+
+constexpr uint64_t JPEG_INFO_SAMPLE_111111 = 0x010101010101;
+constexpr uint64_t JPEG_INFO_SAMPLE_121111 = 0x010201010101;
+constexpr uint64_t JPEG_INFO_SAMPLE_211111 = 0x020101010101;
+constexpr uint64_t JPEG_INFO_SAMPLE_221111 = 0x020201010101;
+constexpr uint8_t BYTE_COUNT = 8;
+constexpr uint8_t JPEG_COMPNENT_NUM_ALPHA = 1;
+constexpr uint8_t JPEG_COMPNENT_NUM_RGB = 3;
+constexpr uint8_t NEXT_POS_NUM_TWO = 2;
+
+bool HwJpegDecompressorAdapter::HardwareDecode(const jpeg_decompress_struct *jpgDinfo, const uint8_t *inputData,
+ size_t bufferSize, DecodeContext &context)
+{
+ if (jpgDinfo == nullptr || inputData == nullptr || inBufHnd_ == nullptr) {
+ HiLog::Error(LABEL, "hardware decompress error, input parameter is null.");
+ return false;
+ }
+ // find the compress data start position.
+ size_t compressPos = GetCompressPos(inputData, bufferSize);
+ if (compressPos == 0) {
+ HiLog::Error(LABEL, "get compress data addr abnormal, compressPos:%{public}zu.", compressPos);
+ return false;
+ }
+ // get decode info for HAL from libjpeg struct.
+ jpeg_decompress_hidl_t decInfo;
+ if (!GetDecodeInfo(jpgDinfo, &decInfo)) {
+ HiLog::Error(LABEL, "get HAL decode info failed.");
+ return false;
+ }
+ // do hardware decode.
+ hwdecode_region_info regionInfo;
+ errno_t ret = memset_s(®ionInfo, sizeof(regionInfo), 0, sizeof(regionInfo));
+ if (ret != EOK) {
+ HiLog::Error(LABEL, "region info memset failed, error_type: %{public}d.", ret);
+ return false;
+ }
+ // alloc output buffer.
+ native_handle_t *outBufHnd = nullptr;
+ uint8_t *outputData = GetOutputBuffer(jpgDinfo, outBufHnd);
+ if (outputData == nullptr) {
+ HiLog::Error(LABEL, "get output buffer failed, alloc buffer error.");
+ return false;
+ }
+ uint32_t sampleSize = 1; // default sample size.
+ if (jpegDecode_->DoDecode(decInfo, android::hardware::hidl_handle(outBufHnd),
+ android::hardware::hidl_handle(inBufHnd_), regionInfo, sampleSize,
+ compressPos) != JPEG_Error::NONE) {
+ HiLog::Error(LABEL, "hardware jpeg decoder decompress image failed.");
+ ReleaseBuffer(outputData, outBufHnd, static_cast(outBufHnd)->alignSize);
+ return false;
+ }
+ context.pixelsBuffer.buffer = outputData;
+ context.pixelsBuffer.context = outBufHnd;
+ context.pixelsBuffer.bufferSize = static_cast(outBufHnd)->alignSize;
+ context.allocatorType = AllocatorType::CUSTOM_ALLOC;
+ context.freeFunc = ReleaseBuffer;
+ return true;
+}
+
+int32_t HwJpegDecompressorAdapter::ComputeDecodeOutColorFormat(uint32_t colorFormat)
+{
+ // note:the third-party RGBA correspond hisi BGRA
+ int32_t outputColorFormat = HISI_JPEG_DECODE_OUT_UNKNOWN;
+ switch (colorFormat) {
+ case JCS_EXT_RGBA: {
+ outputColorFormat = HISI_JPEG_DECODE_OUT_BGRA8888;
+ break;
+ }
+ case JCS_RGB565: {
+ outputColorFormat = HISI_JPEG_DECODE_OUT_RGB565;
+ break;
+ }
+ case JCS_EXT_BGRA: {
+ outputColorFormat = HISI_JPEG_DECODE_OUT_RGBA8888;
+ break;
+ }
+ default: {
+ HiLog::Error(LABEL, "libjpeg decode format:[%{public}d] is unsupported!", colorFormat);
+ break;
+ }
+ }
+ return outputColorFormat;
+}
+
+uint8_t *HwJpegDecompressorAdapter::GetOutputBuffer(const jpeg_decompress_struct *cinfo, native_handle_t *&handle)
+{
+ if (cinfo == nullptr) {
+ HiLog::Error(LABEL, "get output buffer failed, jpeg decompress info is null!");
+ return nullptr;
+ }
+ uint32_t width = cinfo->output_width;
+ uint32_t height = cinfo->output_height;
+ uint32_t colorFormat = cinfo->out_color_space;
+ JpegOutInfo *outInfo = nullptr;
+ void *outBufMapAddr = nullptr;
+ int32_t outputColorFormat = ComputeDecodeOutColorFormat(colorFormat);
+ jpegDecode_->Alloc_OutBuffer(width, height, outputColorFormat, [&](const auto &allocrlt, const auto &buffer) {
+ if (allocrlt == JPEG_Error::NONE) {
+ handle = native_handle_clone(((android::hardware::hidl_handle)buffer).getNativeHandle());
+ }
+ });
+ if (handle == nullptr) {
+ HiLog::Error(LABEL, "jpeg hal failed to alloc output buffer.");
+ return nullptr;
+ }
+ outInfo = static_cast(handle);
+ outBufMapAddr = mmap(nullptr, outInfo->alignSize, PROT_READ | PROT_WRITE, MAP_SHARED, outInfo->data[0], 0);
+ if (outBufMapAddr == MAP_FAILED) {
+ HiLog::Error(LABEL, "output buffer map abnormal.");
+ ReleaseBuffer(nullptr, handle, 0);
+ return nullptr;
+ }
+ return static_cast(outBufMapAddr);
+}
+
+void HwJpegDecompressorAdapter::ReleaseBuffer(void *addr, void *context, uint32_t size)
+{
+ native_handle_t *handle = static_cast(context);
+ if (addr != nullptr) {
+ munmap(addr, size);
+ }
+ if (handle != nullptr) {
+ native_handle_close(handle);
+ native_handle_delete(handle);
+ }
+}
+
+void HwJpegDecompressorAdapter::ReleaseInputBuffer(uint8_t *addr)
+{
+ uint32_t inBufSize = 0;
+ if (inBufHnd_ != nullptr) {
+ inBufSize = static_cast(inBufHnd_)->alignSize;
+ }
+ ReleaseBuffer(addr, inBufHnd_, inBufSize);
+ inBufHnd_ = nullptr;
+}
+
+bool HwJpegDecompressorAdapter::LockDevice()
+{
+ jpegDecode_ = IJpegDecode::tryGetService();
+ if (jpegDecode_.get() == nullptr) {
+ HiLog::Error(LABEL, "get hardware jpeg service failed.");
+ return false;
+ }
+ if (jpegDecode_->LockDevice() != JPEG_Error::NONE) {
+ HiLog::Error(LABEL, "lock hardware device failed.");
+ return false;
+ }
+ return true;
+}
+
+void HwJpegDecompressorAdapter::UnlockDevice()
+{
+ if (jpegDecode_.get() == nullptr) {
+ return;
+ }
+ jpegDecode_->UnLockDevice();
+}
+
+bool HwJpegDecompressorAdapter::FillHuffTable(const JHUFF_TBL *inHuffTable, jpeg_huff_hidl_tbl &outHuffTable)
+{
+ errno_t ret = EOK;
+ if (inHuffTable != nullptr) {
+ outHuffTable.table_flag = true;
+ ret = memcpy_s(&outHuffTable.bits[0], JPEG_INFO_BITS_LENGTH, &inHuffTable->bits[0], JPEG_INFO_BITS_LENGTH);
+ if (ret != EOK) {
+ HiLog::Error(LABEL, "huff table memcpy failed, error_type: %{public}d.", ret);
+ return false;
+ }
+ ret = memcpy_s(&outHuffTable.huffval[0], JPEG_INFO_HUFFVAL_LENGTH, &inHuffTable->huffval[0],
+ JPEG_INFO_HUFFVAL_LENGTH);
+ if (ret != EOK) {
+ HiLog::Error(LABEL, "huff value memcpy failed, error_type: %{public}d.", ret);
+ return false;
+ }
+ } else {
+ ret = memset_s(&outHuffTable, sizeof(outHuffTable), 0, sizeof(outHuffTable));
+ if (ret != EOK) {
+ HiLog::Error(LABEL, "huff table memset failed, error_type: %{public}d.", ret);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool HwJpegDecompressorAdapter::FillQuantTable(const JQUANT_TBL *inQuantTable, jpeg_quant_hidl_tbl &outQuantTable)
+{
+ errno_t ret = EOK;
+ if (inQuantTable != nullptr) {
+ outQuantTable.table_flag = true;
+ ret = memcpy_s(&outQuantTable.quantval[0], DCTSIZE2 * sizeof(uint16_t), &inQuantTable->quantval[0],
+ DCTSIZE2 * sizeof(uint16_t));
+ if (ret != EOK) {
+ HiLog::Error(LABEL, "quant table memcpy failed, error_type: %{public}d.", ret);
+ return false;
+ }
+ } else {
+ ret = memset_s(&outQuantTable, sizeof(outQuantTable), 0, sizeof(outQuantTable));
+ if (ret != EOK) {
+ HiLog::Error(LABEL, "quant table memset failed, error_type: %{public}d.", ret);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool HwJpegDecompressorAdapter::FillComponentInfo(const jpeg_decompress_struct *jpgDinfo,
+ jpeg_decompress_hidl_t *decInfo)
+{
+ if (decInfo == nullptr || jpgDinfo == nullptr) {
+ HiLog::Error(LABEL, "fill component info error, input parameter is null.");
+ return false;
+ }
+ decInfo->comp_info.resize(jpgDinfo->num_components);
+ for (int32_t i = 0; i < jpgDinfo->num_components; i++) {
+ jpeg_comp_hidl_info compInfo;
+ compInfo.h_samp_factor = jpgDinfo->comp_info[i].h_samp_factor;
+ compInfo.v_samp_factor = jpgDinfo->comp_info[i].v_samp_factor;
+ compInfo.quant_tbl_no = jpgDinfo->comp_info[i].quant_tbl_no;
+ compInfo.component_index = jpgDinfo->comp_info[i].component_index;
+ compInfo.component_id = jpgDinfo->comp_info[i].component_id;
+ compInfo.dc_tbl_no = jpgDinfo->comp_info[i].dc_tbl_no;
+ compInfo.ac_tbl_no = jpgDinfo->comp_info[i].ac_tbl_no;
+ compInfo.info_flag = true;
+ decInfo->comp_info[i] = compInfo;
+ }
+ return true;
+}
+
+bool HwJpegDecompressorAdapter::GetDecodeInfo(const jpeg_decompress_struct *jpgDinfo, jpeg_decompress_hidl_t *decInfo)
+{
+ if (decInfo == nullptr || jpgDinfo == nullptr) {
+ HiLog::Error(LABEL, "get decode info input parameter is null.");
+ return false;
+ }
+ decInfo->num_components = jpgDinfo->num_components;
+ decInfo->arith_code = jpgDinfo->arith_code;
+ decInfo->data_precision = jpgDinfo->data_precision;
+ decInfo->image_height = jpgDinfo->image_height;
+ decInfo->image_width = jpgDinfo->image_width;
+ decInfo->progressive_mode = jpgDinfo->progressive_mode;
+ decInfo->restart_interval = jpgDinfo->restart_interval;
+ if (!FillComponentInfo(jpgDinfo, decInfo)) {
+ HiLog::Error(LABEL, "fill component info failed.");
+ return false;
+ }
+ decInfo->dc_huff_tbl_ptrs.resize(NUM_HUFF_TBLS);
+ decInfo->ac_huff_tbl_ptrs.resize(NUM_HUFF_TBLS);
+ for (int32_t i = 0; i < NUM_HUFF_TBLS; i++) {
+ jpeg_huff_hidl_tbl huffTable;
+ if (!FillHuffTable(jpgDinfo->dc_huff_tbl_ptrs[i], huffTable)) {
+ HiLog::Error(LABEL, "fill dc huff table failed.");
+ return false;
+ }
+ decInfo->dc_huff_tbl_ptrs[i] = huffTable;
+ if (!FillHuffTable(jpgDinfo->ac_huff_tbl_ptrs[i], huffTable)) {
+ HiLog::Error(LABEL, "fill ac huff table failed.");
+ return false;
+ }
+ decInfo->ac_huff_tbl_ptrs[i] = huffTable;
+ }
+ decInfo->quant_tbl_ptrs.resize(NUM_QUANT_TBLS);
+ for (int32_t i = 0; i < NUM_QUANT_TBLS; i++) {
+ jpeg_quant_hidl_tbl quantTable;
+ if (!FillQuantTable(jpgDinfo->quant_tbl_ptrs[i], quantTable)) {
+ HiLog::Error(LABEL, "fill quant table failed.");
+ return false;
+ }
+ decInfo->quant_tbl_ptrs[i] = quantTable;
+ }
+ return true;
+}
+
+bool HwJpegDecompressorAdapter::CheckHardwareSupport(const jpeg_decompress_struct *cinfo)
+{
+ if (cinfo == nullptr) {
+ HiLog::Error(LABEL, "check hardware support failed, input parameter error!");
+ return false;
+ }
+ if (((cinfo->num_components != JPEG_COMPNENT_NUM_ALPHA) && (cinfo->num_components != JPEG_COMPNENT_NUM_RGB)) ||
+ (cinfo->arith_code) || (cinfo->progressive_mode) || (cinfo->data_precision != BYTE_COUNT)) {
+ HiLog::Error(LABEL,
+ "hardware decoder cannot handle num_components:%{public}d, progressive_mode:%{public}d, "
+ "data_precision:%{public}d.",
+ cinfo->num_components, cinfo->progressive_mode, cinfo->data_precision);
+ return false;
+ }
+ if (cinfo->comp_info == nullptr) {
+ HiLog::Error(LABEL, "jpeg decompress info factor is null.");
+ return false;
+ }
+ // JPEG hardware decode only support 111111 121111 211111 221111 and xx0000
+ // h_samp_factor/v_samp_factor in range (0...255)
+ uint64_t sampleValue = 0;
+ for (int32_t i = 0; i < cinfo->num_components; i++) {
+ sampleValue = sampleValue << BYTE_COUNT;
+ sampleValue |= (static_cast(cinfo->comp_info[i].h_samp_factor) & 0xFF);
+ sampleValue = sampleValue << BYTE_COUNT;
+ sampleValue |= (static_cast(cinfo->comp_info[i].v_samp_factor) & 0xFF);
+ }
+ switch (sampleValue) {
+ case JPEG_INFO_SAMPLE_111111:
+ case JPEG_INFO_SAMPLE_121111:
+ case JPEG_INFO_SAMPLE_211111:
+ case JPEG_INFO_SAMPLE_221111:
+ return true;
+ default: {
+ if ((sampleValue & 0xFFFFFFFF) == 0) {
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+size_t HwJpegDecompressorAdapter::GetCompressPos(const uint8_t *inBufMapAddr, size_t bufferSize)
+{
+ const uint8_t *curr = inBufMapAddr;
+ size_t lh = 0;
+ size_t ll = 0;
+ size_t pos = 0;
+ size_t ret = 0;
+ while (bufferSize > (pos + NEXT_POS_NUM_TWO) && *curr++ == 0xff) {
+ uint8_t value = *curr++;
+ pos += NEXT_POS_NUM_TWO;
+ if (value == 0xD8 || value == 0xD9) {
+ continue;
+ }
+ if ((pos + NEXT_POS_NUM_TWO) > bufferSize) {
+ HiLog::Warn(LABEL, "next pos %{public}zu may be large than bufferSize %{public}zu", pos, bufferSize);
+ break;
+ }
+ lh = *curr;
+ ll = *(curr + 1);
+ curr += (lh << BYTE_COUNT) + ll;
+ pos = curr - inBufMapAddr;
+ HiLog::Debug(LABEL, "pos %{public}zu, lh = %{public}zx, ll = %{public}zx ", pos, lh, ll);
+ if (value == 0xDA) {
+ ret = pos;
+ break;
+ }
+ }
+ return ret;
+}
+
+uint8_t *HwJpegDecompressorAdapter::GetInputBuffer(size_t bufferSize)
+{
+ void *inBufMapAddr = nullptr;
+ jpegDecode_->Alloc_InBuffer(bufferSize, [&](const auto &tmpError, const auto &tmpbuffer) {
+ if (tmpError == JPEG_Error::NONE) {
+ inBufHnd_ = native_handle_clone(((android::hardware::hidl_handle)tmpbuffer).getNativeHandle());
+ }
+ });
+ if (inBufHnd_ == nullptr) {
+ HiLog::Error(LABEL, "alloc input buffer failed.");
+ return nullptr;
+ }
+ JpegInInfo *inInfo = static_cast(inBufHnd_);
+ inBufMapAddr = mmap(nullptr, inInfo->alignSize, PROT_READ | PROT_WRITE, MAP_SHARED, inInfo->data[0], 0);
+ if (inBufMapAddr == MAP_FAILED) {
+ ReleaseInputBuffer(nullptr);
+ return nullptr;
+ }
+ return static_cast(inBufMapAddr);
+}
+} // namespace Media
+} // namespace OHOS
\ No newline at end of file
diff --git a/adapter/frameworks/libbmpplugin/BUILD.gn_old b/adapter/frameworks/libbmpplugin/BUILD.gn_old
new file mode 100644
index 0000000000000000000000000000000000000000..e53c7c4f42cdf98fb0c9bf7a48de29188cb2df00
--- /dev/null
+++ b/adapter/frameworks/libbmpplugin/BUILD.gn_old
@@ -0,0 +1,94 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+import("//foundation/multimedia/image_standard/ide/image_decode_config.gni")
+
+ohos_shared_library("bmpplugin") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/libbmpplugin/src/bmp_decoder.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libbmpplugin/src/bmp_stream.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libbmpplugin/src/plugin_export.cpp",
+ ]
+
+ include_dirs = [
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include/image",
+ "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libbmpplugin/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include",
+ "//third_party/flutter/skia/include/codec",
+ "//third_party/flutter/skia/third_party/externals/libjpeg-turbo",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/third_party/libjpeg-turbo",
+ "//third_party/flutter/skia",
+ ]
+ if (use_mingw_win) {
+ defines = image_decode_windows_defines
+ include_dirs += [
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "//foundation/multimedia/image_standard/mock/native/include/secure",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/win",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ ]
+ deps = [
+ "//foundation/graphic/ide/libs/skia:skia",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils_static",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static",
+ ]
+
+ libs = [ "//foundation/multimedia/image_standard/libskia.lib" ]
+ } else if (use_clang_mac) {
+ defines = image_decode_mac_defines
+ include_dirs += [
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/mac",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ "//utils/native/base/include",
+ ]
+ deps = [
+ "//foundation/graphic/ide/libs/skia:skia",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils_static",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static",
+ "//utils/native/base:utilsecurec",
+ ]
+ } else {
+ include_dirs += [ "//utils/native/base/include" ]
+ deps = [
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+ "//utils/native/base:utils",
+ ]
+
+# external_deps = [ "hilog:libhilog" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+# aosp_deps = [ "shared_library:libhwui" ]
+ }
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
+
+ohos_prebuilt_etc("bmppluginmetadata") {
+ source = "bmpplugin.pluginmeta"
+ relative_install_dir = "multimediaplugin/image"
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/libbmpplugin/bmpplugin.pluginmeta b/adapter/frameworks/libbmpplugin/bmpplugin.pluginmeta
new file mode 100755
index 0000000000000000000000000000000000000000..0ffc1cac68e8343cc6bf4f6ad4c875cfb288428b
--- /dev/null
+++ b/adapter/frameworks/libbmpplugin/bmpplugin.pluginmeta
@@ -0,0 +1,25 @@
+{
+ "packageName":"LibBmpPlugin",
+ "version":"1.0.0.0",
+ "targetVersion":"1.0.0.0",
+ "libraryPath":"libbmpplugin.z.so",
+ "classes": [
+ {
+ "className":"OHOS::ImagePlugin::BmpDecoder",
+ "services": [
+ {
+ "interfaceID":2,
+ "serviceType":0
+ }
+ ],
+ "priority":100,
+ "capabilities": [
+ {
+ "name":"encodeFormat",
+ "type":"string",
+ "value": "image/bmp"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapter/frameworks/libbmpplugin/include/bmp_decoder.h b/adapter/frameworks/libbmpplugin/include/bmp_decoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..356db0bd5643dc8c8cfb7906b6644614ed981bd1
--- /dev/null
+++ b/adapter/frameworks/libbmpplugin/include/bmp_decoder.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2021 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 BMP_DECODER_H
+#define BMP_DECODER_H
+
+#include
+#include
+#include "SkCodec.h"
+#include "abs_image_decoder.h"
+#include "bmp_stream.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "plugin_class_base.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+enum class BmpDecodingState : int32_t {
+ UNDECIDED = 0,
+ SOURCE_INITED = 1,
+ BASE_INFO_PARSED = 2,
+ IMAGE_DECODING = 3,
+ IMAGE_ERROR = 4,
+ IMAGE_DECODED = 5
+};
+
+class BmpDecoder : public AbsImageDecoder, public OHOS::MultimediaPlugin::PluginClassBase {
+public:
+ BmpDecoder() = default;
+ virtual ~BmpDecoder() override{};
+ void SetSource(InputDataStream &sourceStream) override;
+ void Reset() override;
+ uint32_t SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info) override;
+ uint32_t Decode(uint32_t index, DecodeContext &context) override;
+ uint32_t GetImageSize(uint32_t index, PlSize &size) override;
+ uint32_t PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context) override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(BmpDecoder);
+ bool DecodeHeader();
+ PlAlphaType ConvertToAlphaType(SkAlphaType alphaType);
+ SkColorType ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat);
+ InputDataStream *stream_ = nullptr;
+ std::unique_ptr codec_ = nullptr;
+ SkImageInfo info_;
+ SkColorType desireColor_ = kUnknown_SkColorType;
+ BmpDecodingState state_ = BmpDecodingState::UNDECIDED;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // BMP_DECODER_H
diff --git a/adapter/frameworks/libbmpplugin/include/bmp_stream.h b/adapter/frameworks/libbmpplugin/include/bmp_stream.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9f65e13f250b9c8f47e202bd2cca0dcae9fbce1
--- /dev/null
+++ b/adapter/frameworks/libbmpplugin/include/bmp_stream.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 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 BMP_STREAM_H
+#define BMP_STREAM_H
+
+#include
+#include
+#include "SkStream.h"
+#include "hilog/log.h"
+#include "input_data_stream.h"
+#include "log_tags.h"
+#include "nocopyable.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+class BmpStream : public SkStream {
+public:
+ BmpStream() = default;
+ explicit BmpStream(InputDataStream *stream);
+ virtual ~BmpStream() override{};
+ /**
+ * Reads or skips size number of bytes.
+ * if buffer is null, skip size bytes, return how many bytes skipped.
+ * else copy size bytes into buffer, return how many bytes copied.
+ */
+ size_t read(void *buffer, size_t size) override;
+ /**
+ * Peeks size number of bytes.
+ */
+ size_t peek(void *buffer, size_t size) const override;
+ /**
+ * Returns true when all the bytes in the stream have been read.
+ */
+ bool isAtEnd() const override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(BmpStream);
+ ImagePlugin::InputDataStream *inputStream_ = nullptr;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // BMP_STREAM_H
\ No newline at end of file
diff --git a/adapter/frameworks/libbmpplugin/src/bmp_decoder.cpp b/adapter/frameworks/libbmpplugin/src/bmp_decoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ea964a16bf9106393b83f9456a98b702f63db40d
--- /dev/null
+++ b/adapter/frameworks/libbmpplugin/src/bmp_decoder.cpp
@@ -0,0 +1,262 @@
+/*
+ * Copyright (C) 2021 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 "bmp_decoder.h"
+#include "image_utils.h"
+#include "media_errors.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+using namespace Media;
+using namespace std;
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "BmpDecoder" };
+namespace {
+constexpr uint32_t BMP_IMAGE_NUM = 1;
+}
+
+void BmpDecoder::SetSource(InputDataStream &sourceStream)
+{
+ stream_ = &sourceStream;
+ state_ = BmpDecodingState::SOURCE_INITED;
+}
+
+void BmpDecoder::Reset()
+{
+ if (stream_ != nullptr) {
+ stream_->Seek(0);
+ }
+ codec_.release();
+ info_.reset();
+ desireColor_ = kUnknown_SkColorType;
+}
+
+uint32_t BmpDecoder::GetImageSize(uint32_t index, PlSize &size)
+{
+ if (index >= BMP_IMAGE_NUM) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid index:%{public}u, range:%{public}u", index, BMP_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < BmpDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid state:%{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= BmpDecodingState::BASE_INFO_PARSED) {
+ size.width = info_.width();
+ size.height = info_.height();
+ return SUCCESS;
+ }
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ size.width = info_.width();
+ size.height = info_.height();
+ state_ = BmpDecodingState::BASE_INFO_PARSED;
+ return SUCCESS;
+}
+
+uint32_t BmpDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info)
+{
+ if (index >= BMP_IMAGE_NUM) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid index:%{public}u, range:%{public}u", index,
+ BMP_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < BmpDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= BmpDecodingState::IMAGE_DECODING) {
+ Reset();
+ state_ = BmpDecodingState::SOURCE_INITED;
+ }
+ if (state_ < BmpDecodingState::BASE_INFO_PARSED) {
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ state_ = BmpDecodingState::BASE_INFO_PARSED;
+ }
+ PlPixelFormat desiredFormat = opts.desiredPixelFormat;
+ desireColor_ = ConvertToColorType(desiredFormat, info.pixelFormat);
+ info.size.width = info_.width();
+ info.size.height = info_.height();
+ info.alphaType = ConvertToAlphaType(info_.alphaType());
+ state_ = BmpDecodingState::IMAGE_DECODING;
+ return SUCCESS;
+}
+
+uint32_t BmpDecoder::Decode(uint32_t index, DecodeContext &context)
+{
+ if (index >= BMP_IMAGE_NUM) {
+ HiLog::Error(LABEL, "Decode failed, invalid index:%{public}u, range:%{public}u", index, BMP_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (codec_ == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, codec is null");
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+ if (state_ != BmpDecodingState::IMAGE_DECODING) {
+ HiLog::Error(LABEL, "Decode failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+
+ SkImageInfo dstInfo = info_.makeColorType(desireColor_);
+ if (ImageUtils::CheckMulOverflow(dstInfo.width(), dstInfo.height(), dstInfo.bytesPerPixel())) {
+ HiLog::Error(LABEL, "Decode failed, width:%{public}d, height:%{public}d is too large",
+ dstInfo.width(), dstInfo.height());
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+ if (context.pixelsBuffer.buffer == nullptr) {
+ uint64_t byteCount = static_cast(dstInfo.height()) * dstInfo.width() * dstInfo.bytesPerPixel();
+ if (context.allocatorType == Media::AllocatorType::SHARE_MEM_ALLOC) {
+#if !defined(_WIN32) && !defined(_APPLE)
+ int fd = AshmemCreate("BMP RawData", byteCount);
+ if (fd < 0) {
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
+ if (result < 0) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ void* ptr = ::mmap(nullptr, byteCount, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ context.pixelsBuffer.buffer = ptr;
+ void *fdBuffer = new int32_t();
+ if (fdBuffer == nullptr) {
+ HiLog::Error(LABEL, "new fdBuffer fail");
+ ::munmap(ptr, byteCount);
+ ::close(fd);
+ context.pixelsBuffer.buffer = nullptr;
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ *static_cast(fdBuffer) = fd;
+ context.pixelsBuffer.context = fdBuffer;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
+ context.freeFunc = nullptr;
+#endif
+ } else {
+ void *outputBuffer = malloc(byteCount);
+ if (outputBuffer == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, alloc output buffer size:[%{public}llu] error",
+ static_cast(byteCount));
+ return ERR_IMAGE_MALLOC_ABNORMAL;
+ }
+#ifdef _WIN32
+ memset(outputBuffer, 0, byteCount);
+#else
+ if (memset_s(outputBuffer, byteCount, 0, byteCount) != EOK) {
+ HiLog::Error(LABEL, "Decode failed, memset buffer failed");
+ free(outputBuffer);
+ outputBuffer = nullptr;
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+#endif
+ context.pixelsBuffer.buffer = outputBuffer;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.pixelsBuffer.context = nullptr;
+ context.allocatorType = AllocatorType::HEAP_ALLOC;
+ context.freeFunc = nullptr;
+ }
+ }
+ uint8_t *dstBuffer = static_cast(context.pixelsBuffer.buffer);
+ size_t rowBytes = dstInfo.width() * dstInfo.bytesPerPixel();
+ SkCodec::Result ret = codec_->getPixels(dstInfo, dstBuffer, rowBytes);
+ if (ret != SkCodec::kSuccess) {
+ HiLog::Error(LABEL, "Decode failed, get pixels failed, ret=%{public}d", ret);
+ state_ = BmpDecodingState::IMAGE_ERROR;
+ return ERR_IMAGE_DECODE_ABNORMAL;
+ }
+ state_ = BmpDecodingState::IMAGE_DECODED;
+ return SUCCESS;
+}
+
+uint32_t BmpDecoder::PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context)
+{
+ // currently not support increment decode
+ return ERR_IMAGE_DATA_UNSUPPORT;
+}
+
+bool BmpDecoder::DecodeHeader()
+{
+ codec_ = SkCodec::MakeFromStream(make_unique(stream_));
+ if (codec_ == nullptr) {
+ HiLog::Error(LABEL, "create codec from stream failed");
+ return false;
+ }
+ info_ = codec_->getInfo();
+ return true;
+}
+
+PlAlphaType BmpDecoder::ConvertToAlphaType(SkAlphaType alphaType)
+{
+ switch (alphaType) {
+ case kOpaque_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
+ case kPremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_PREMUL;
+ case kUnpremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
+ default:
+ HiLog::Error(LABEL, "known alpha type:%{public}d", alphaType);
+ break;
+ }
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
+}
+
+SkColorType BmpDecoder::ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat)
+{
+ switch (format) {
+ case PlPixelFormat::UNKNOWN:
+ case PlPixelFormat::RGBA_8888: {
+ outputFormat = PlPixelFormat::RGBA_8888;
+ return kRGBA_8888_SkColorType;
+ }
+ case PlPixelFormat::BGRA_8888: {
+ outputFormat = PlPixelFormat::BGRA_8888;
+ return kBGRA_8888_SkColorType;
+ }
+ case PlPixelFormat::ALPHA_8: {
+ SkColorType colorType = info_.colorType();
+ if (colorType == kAlpha_8_SkColorType || (colorType == kGray_8_SkColorType && info_.isOpaque())) {
+ outputFormat = PlPixelFormat::ALPHA_8;
+ return kAlpha_8_SkColorType;
+ }
+ break;
+ }
+ case PlPixelFormat::RGB_565: {
+ if (info_.isOpaque()) {
+ outputFormat = PlPixelFormat::RGB_565;
+ return kRGB_565_SkColorType;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ HiLog::Debug(LABEL, "unsupported convert to format:%{public}d, set default RGBA", format);
+ outputFormat = PlPixelFormat::RGBA_8888;
+ return kRGBA_8888_SkColorType;
+}
+} // namespace ImagePlugin
+} // namespace OHOS
\ No newline at end of file
diff --git a/adapter/frameworks/libbmpplugin/src/bmp_stream.cpp b/adapter/frameworks/libbmpplugin/src/bmp_stream.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6694bce8bed4098442a5bbe0b21624db89f8214e
--- /dev/null
+++ b/adapter/frameworks/libbmpplugin/src/bmp_stream.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2021 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 "bmp_stream.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "BmpStream" };
+BmpStream::BmpStream(InputDataStream *stream) : inputStream_(stream) {}
+
+size_t BmpStream::read(void *buffer, size_t size)
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "read failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ size_t curPosition = static_cast(inputStream_->Tell());
+ if (!inputStream_->Seek(curPosition + size)) {
+ HiLog::Error(LABEL, "read failed, curpositon=%{public}zu, skip size=%{public}zu", curPosition, size);
+ return 0;
+ }
+ return size;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Read(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "read failed, desire read size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+size_t BmpStream::peek(void *buffer, size_t size) const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "peek failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ HiLog::Error(LABEL, "peek failed, output buffer is null");
+ return 0;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Peek(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "peek failed, desire peek size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+bool BmpStream::isAtEnd() const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "get stream status failed, inputStream_ is null.");
+ return false;
+ }
+ size_t size = inputStream_->GetStreamSize();
+ return (inputStream_->Tell() == size);
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/libbmpplugin/src/plugin_export.cpp b/adapter/frameworks/libbmpplugin/src/plugin_export.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e109dfbf5a44560a16d8741d58e6a75a9a92f90c
--- /dev/null
+++ b/adapter/frameworks/libbmpplugin/src/plugin_export.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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 "plugin_export.h"
+#include "bmp_decoder.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "plugin_utils.h"
+
+// plugin package name same as metadata.
+PLUGIN_EXPORT_REGISTER_PACKAGE("LibBmpPlugin")
+
+// register implement classes of this plugin.
+PLUGIN_EXPORT_REGISTER_CLASS_BEGIN
+PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::BmpDecoder)
+PLUGIN_EXPORT_REGISTER_CLASS_END
+
+using namespace OHOS::HiviewDFX;
+
+static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibBmpPlugin" };
+
+#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__);
+#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__);
+
+// define the external interface of this plugin.
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_START()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE()
diff --git a/adapter/frameworks/libhwjpegplugin/BUILD.gn_old b/adapter/frameworks/libhwjpegplugin/BUILD.gn_old
new file mode 100644
index 0000000000000000000000000000000000000000..72a9129e5f09c8aa102802aad28f667e9d480b09
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/BUILD.gn_old
@@ -0,0 +1,82 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+
+ohos_shared_library("hwjpegplugin") {
+ ###### For OHOS adapter define begin #####
+ # Use Adapter: define "DUAL_ADAPTER"
+ # Abandon Adapter: delete the define "DUAL_ADAPTER"
+ defines = [ "DUAL_ADAPTER" ]
+
+ # Use Adapter: Set DUAL_ADAPTER true
+ # Abandon Adapter: Set DUAL_ADAPTER false
+ DUAL_ADAPTER = true
+
+ ###### For OHOS adapter define end #####
+
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor_wrapper.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libhwjpegplugin/src/plugin_export.cpp",
+ ]
+
+ include_dirs = [
+ "//utils/native/base/include",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include",
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include/image",
+ "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libhwjpegplugin/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/adapter/frameworks/hwjpegcodec/include",
+ "//third_party/flutter/skia/third_party/externals/libjpeg-turbo",
+ "//third_party/flutter/skia/include/codec",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/third_party/libjpeg-turbo",
+ ]
+
+ deps = [
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+ "//utils/native/base:utils",
+ ]
+
+ if (DUAL_ADAPTER) {
+ deps += [ "//foundation/multimedia/image_standard/adapter/frameworks/hwjpegcodec:hwjpegadapter" ]
+# aosp_deps = [
+# "shared_library:libcutils",
+# "shared_library:libhidlbase",
+# "shared_library:libjpeg",
+# "shared_library:libutils",
+# "shared_library:vendor.huawei.hardware.jpegdec@1.0",
+# ]
+ } else {
+ deps += [ "//third_party/libjpeg-turbo:libjpeg-turbo" ]
+ include_dirs += [ "//third_party/libjpeg-turbo" ]
+ }
+
+# external_deps = [ "hilog:libhilog" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+
+ part_name = "multimedia_image"
+
+ subsystem_name = "multimedia"
+}
+
+ohos_prebuilt_etc("hwjpegpluginmetadata") {
+ source = "hwjpegplugin.pluginmeta"
+ relative_install_dir = "multimediaplugin/image"
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/libhwjpegplugin/hwjpegplugin.pluginmeta b/adapter/frameworks/libhwjpegplugin/hwjpegplugin.pluginmeta
new file mode 100644
index 0000000000000000000000000000000000000000..4af51f517cf86c43e43225349bae5aa904c8b474
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/hwjpegplugin.pluginmeta
@@ -0,0 +1,25 @@
+{
+ "packageName":"LibHwJpegPlugin",
+ "version":"1.0.0.0",
+ "targetVersion":"1.0.0.0",
+ "libraryPath":"libhwjpegplugin.z.so",
+ "classes": [
+ {
+ "className":"OHOS::ImagePlugin::HwJpegDecompressor",
+ "services": [
+ {
+ "interfaceID":4,
+ "serviceType":0
+ }
+ ],
+ "priority":100,
+ "capabilities": [
+ {
+ "name":"encodeFormat",
+ "type":"string",
+ "value": "image/jpeg"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor.h b/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor.h
new file mode 100644
index 0000000000000000000000000000000000000000..96d9f065f7566ac04ee44da57d738fd22f53c086
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2021 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 HW_JPEG_DECOMPRESSOR_H
+#define HW_JPEG_DECOMPRESSOR_H
+
+#include
+#include
+#include "abs_image_decoder.h"
+#include "abs_image_decompress_component.h"
+#include "hilog/log.h"
+#include "hw_jpeg_decompressor_wrapper.h"
+#include "input_data_stream.h"
+#include "jerror.h"
+#include "jpeglib.h"
+#include "log_tags.h"
+#include "plugin_class_base.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+class HwJpegDecompressor : public AbsImageDecompressComponent, public OHOS::MultimediaPlugin::PluginClassBase {
+public:
+ HwJpegDecompressor();
+ ~HwJpegDecompressor() = default;
+ uint32_t Decompress(void *decompressInfo, InputDataStream *stream, DecodeContext &context) override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(HwJpegDecompressor);
+ bool CheckOriginalImageSize(uint32_t srcWidth, uint32_t srcHeight, uint32_t comps);
+ bool CheckOutputImageSize(uint32_t outWidth, uint32_t comps);
+ uint8_t *GetInputBuffer(size_t &bufferSize);
+ uint32_t DoDecompress(DecodeContext &context);
+ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "HwJpegDecompressor"
+ };
+ jpeg_decompress_struct *decodeInfo_ = nullptr;
+ InputDataStream *stream_ = nullptr;
+ std::unique_ptr hwDecompressor_ = nullptr;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // HW_JPEG_DECOMPRESSOR_H
diff --git a/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor_interface.h b/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor_interface.h
new file mode 100644
index 0000000000000000000000000000000000000000..24b2ab8074601e05e517c673d87acd8578d3df68
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor_interface.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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 HW_JPEG_DECOMPRESSOR_INTERFACE_H
+#define HW_JPEG_DECOMPRESSOR_INTERFACE_H
+
+#include
+#include
+#include "abs_image_decoder.h"
+#include "jpeglib.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+class HwJpegDecompressorInterface {
+public:
+ HwJpegDecompressorInterface() = default;
+ virtual ~HwJpegDecompressorInterface() = default;
+ virtual bool LockDevice() = 0;
+ virtual void UnlockDevice() = 0;
+ virtual bool CheckHardwareSupport(const jpeg_decompress_struct *cinfo) = 0;
+ virtual uint8_t *GetInputBuffer(size_t bufferSize) = 0;
+ virtual bool HardwareDecode(const jpeg_decompress_struct *cinfo, const uint8_t *inputData, size_t bufferSize,
+ ImagePlugin::DecodeContext &context) = 0;
+ virtual void ReleaseInputBuffer(uint8_t *addr) = 0;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // HW_JPEG_DECOMPRESSOR_INTERFACE_H
\ No newline at end of file
diff --git a/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor_wrapper.h b/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor_wrapper.h
new file mode 100644
index 0000000000000000000000000000000000000000..5adb27f72e3aa1f9ca4ddb4a108065b4636093d4
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/include/hw_jpeg_decompressor_wrapper.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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 HW_JPEG_DECOMPRESSOR_WRAPPER_H
+#define HW_JPEG_DECOMPRESSOR_WRAPPER_H
+
+#include
+#include "hw_jpeg_decompressor_interface.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+class HwJpegDecompressorWrapper {
+public:
+ static std::unique_ptr CreateHwJpegDecompressor();
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // HW_JPEG_DECOMPRESSOR_WRAPPER_H
\ No newline at end of file
diff --git a/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor.cpp b/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..362e5daebb5ead6ef88ce503f124a113996a26d9
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor.cpp
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2021 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 "hw_jpeg_decompressor.h"
+#include
+#include
+#include "jerror.h"
+#include "media_errors.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+using namespace MultimediaPlugin;
+using namespace Media;
+
+constexpr uint32_t JPEG_SOURCE_SIZE_MAX = 8192;
+constexpr uint32_t JPEG_SOURCE_SIZE_MIN = 512;
+
+HwJpegDecompressor::HwJpegDecompressor()
+{
+ hwDecompressor_ = HwJpegDecompressorWrapper::CreateHwJpegDecompressor();
+}
+
+bool HwJpegDecompressor::CheckOriginalImageSize(uint32_t srcWidth, uint32_t srcHeight, uint32_t comps)
+{
+ // check origal image size.
+ if (srcWidth > JPEG_SOURCE_SIZE_MAX || srcWidth < JPEG_SOURCE_SIZE_MIN || srcHeight > JPEG_SOURCE_SIZE_MAX ||
+ srcHeight < JPEG_SOURCE_SIZE_MIN) {
+ HiLog::Error(LABEL, "image size:[%{public}u, %{public}u] out of hardware range:(%{public}u, %{public}u).",
+ srcWidth, srcHeight, JPEG_SOURCE_SIZE_MIN, JPEG_SOURCE_SIZE_MAX);
+ return false;
+ }
+ // check row bytes is aligned with 128 bits(16 Bytes).
+ uint64_t imageRowBytes = static_cast(srcWidth) * comps;
+ if (imageRowBytes & 0xF) {
+ HiLog::Error(LABEL, "row bytes is not aligned with 16 bytes, row bytes=%{public}llu.",
+ static_cast(imageRowBytes));
+ return false;
+ }
+ return true;
+}
+
+bool HwJpegDecompressor::CheckOutputImageSize(uint32_t outWidth, uint32_t comps)
+{
+ // check output row bytes is aligned with 16 Bytes.
+ uint64_t outputRowBytes = static_cast(outWidth) * comps;
+ if (outputRowBytes & 0xF) {
+ HiLog::Error(LABEL, "output row bytes is not aligned with 16 bytes, row bytes=%{public}llu.",
+ static_cast(outputRowBytes));
+ return false;
+ }
+ return true;
+}
+
+uint8_t *HwJpegDecompressor::GetInputBuffer(size_t &bufferSize)
+{
+ if (stream_ == nullptr || hwDecompressor_ == nullptr) {
+ HiLog::Error(LABEL, "get input buffer failed, stream is null.");
+ return nullptr;
+ }
+ bufferSize = stream_->GetStreamSize();
+ if (bufferSize == 0) {
+ HiLog::Error(LABEL, "get input buffer failed, stream size is zero.");
+ return nullptr;
+ }
+ HiLog::Debug(LABEL, "get stream size=%{public}zu.", bufferSize);
+ uint32_t positionRecord = stream_->Tell();
+ uint8_t *inBufMapAddr = hwDecompressor_->GetInputBuffer(bufferSize);
+ if (inBufMapAddr == nullptr) {
+ HiLog::Error(LABEL, "get input buffer failed, alloc buffer error.");
+ return nullptr;
+ }
+ stream_->Seek(0);
+ uint32_t readSize = 0;
+ stream_->Read(bufferSize, inBufMapAddr, bufferSize, readSize);
+ stream_->Seek(positionRecord);
+ return inBufMapAddr;
+}
+
+uint32_t HwJpegDecompressor::DoDecompress(DecodeContext &context)
+{
+ if (hwDecompressor_ == nullptr) {
+ HiLog::Error(LABEL, "do decompress error, hardware decoder is null.");
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ // check jpeg_decompress_struct is ok for hardware support.
+ if (!hwDecompressor_->CheckHardwareSupport(decodeInfo_)) {
+ HiLog::Error(LABEL, "hardware jpeg decoder cannot support.");
+ return ERR_IMAGE_HW_DECODE_UNSUPPORT;
+ }
+ // file input ion buffer.
+ size_t bufferSize = 0;
+ uint8_t *inputDataAddr = GetInputBuffer(bufferSize);
+ if (!hwDecompressor_->HardwareDecode(decodeInfo_, inputDataAddr, bufferSize, context)) {
+ HiLog::Error(LABEL, "hardware decoder decode image failed.");
+ hwDecompressor_->ReleaseInputBuffer(inputDataAddr);
+ return ERR_IMAGE_DECODE_ABNORMAL;
+ }
+ hwDecompressor_->ReleaseInputBuffer(inputDataAddr);
+ return SUCCESS;
+}
+
+uint32_t HwJpegDecompressor::Decompress(void *decompressInfo, InputDataStream *stream, DecodeContext &context)
+{
+ if (decompressInfo == nullptr || stream == nullptr) {
+ HiLog::Error(LABEL, "jpeg hardware decode error, input parameter is null.");
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ decodeInfo_ = static_cast(decompressInfo);
+ stream_ = stream;
+ uint32_t srcWidth = decodeInfo_->image_width;
+ uint32_t srcHeight = decodeInfo_->image_height;
+ uint32_t srcComps = decodeInfo_->num_components;
+ if (!CheckOriginalImageSize(srcWidth, srcHeight, srcComps)) {
+ HiLog::Error(LABEL, "check original image size failed, hardware jpeg decoder cannot support.");
+ return ERR_IMAGE_HW_DECODE_UNSUPPORT;
+ }
+ uint32_t outWidth = decodeInfo_->output_width;
+ uint32_t outComps = decodeInfo_->output_components;
+ if (!CheckOutputImageSize(outWidth, outComps)) {
+ HiLog::Error(LABEL, "check output image size failed, hardware jpeg decoder cannot support.");
+ return ERR_IMAGE_HW_DECODE_UNSUPPORT;
+ }
+ if (hwDecompressor_ == nullptr) {
+ HiLog::Error(LABEL, "hardware jpeg decoder is null.");
+ return ERR_IMAGE_DECODE_ABNORMAL;
+ }
+ // get hardware service
+ if (!hwDecompressor_->LockDevice()) {
+ HiLog::Error(LABEL, "lock hardware device failed!");
+ return ERR_IMAGE_DECODE_ABNORMAL;
+ }
+ uint32_t ret = DoDecompress(context);
+ hwDecompressor_->UnlockDevice();
+ return ret;
+}
+} // namespace ImagePlugin
+} // namespace OHOS
\ No newline at end of file
diff --git a/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor_wrapper.cpp b/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor_wrapper.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..efdb118449cf126f4b8fc6c3832c61dee602813f
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/src/hw_jpeg_decompressor_wrapper.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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 "hw_jpeg_decompressor_wrapper.h"
+
+#ifdef DUAL_ADAPTER
+#include "hw_jpeg_decompressor_adapter.h"
+#endif
+
+namespace OHOS {
+namespace ImagePlugin {
+std::unique_ptr HwJpegDecompressorWrapper::CreateHwJpegDecompressor()
+{
+#ifdef DUAL_ADAPTER
+ return std::make_unique();
+#else
+ return nullptr;
+#endif
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/libhwjpegplugin/src/plugin_export.cpp b/adapter/frameworks/libhwjpegplugin/src/plugin_export.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4dffac42e131a136b4d0dc7db4a07ed25562c89e
--- /dev/null
+++ b/adapter/frameworks/libhwjpegplugin/src/plugin_export.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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 "plugin_export.h"
+#include "hilog/log.h"
+#include "hw_jpeg_decompressor.h"
+#include "log_tags.h"
+#include "plugin_utils.h"
+
+// plugin package name same as metadata.
+PLUGIN_EXPORT_REGISTER_PACKAGE("LibHwJpegPlugin")
+
+// register implement classes of this plugin.
+PLUGIN_EXPORT_REGISTER_CLASS_BEGIN
+PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::HwJpegDecompressor)
+PLUGIN_EXPORT_REGISTER_CLASS_END
+
+using namespace OHOS::HiviewDFX;
+
+static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibHwJpegPlugin" };
+
+#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__);
+#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__);
+
+// define the external interface of this plugin.
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_START()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE()
diff --git a/adapter/frameworks/librawplugin/BUILD.gn_old b/adapter/frameworks/librawplugin/BUILD.gn_old
new file mode 100644
index 0000000000000000000000000000000000000000..f609ae1fd1c8449900ae8a6861abf0d621defe04
--- /dev/null
+++ b/adapter/frameworks/librawplugin/BUILD.gn_old
@@ -0,0 +1,90 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+import("//foundation/multimedia/image_standard/ide/image_decode_config.gni")
+
+ohos_shared_library("rawplugin") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/librawplugin/src/plugin_export.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/librawplugin/src/raw_decoder.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/librawplugin/src/raw_stream.cpp",
+ ]
+
+ include_dirs = [
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include/image",
+ "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase",
+ "//foundation/multimedia/image_standard/adapter/frameworks/librawplugin/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include",
+ "//third_party/flutter/skia/include/codec",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/include/core",
+
+ ]
+ if (use_mingw_win) {
+ defines = image_decode_windows_defines
+ include_dirs += [
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "//foundation/multimedia/image_standard/mock/native/include/secure",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/win",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ ]
+ deps = [
+ "//foundation/graphic/ide/libs/skia:skia",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static",
+ "//third_party/flutter:ace_skia_core",
+ "//third_party/flutter:ace_fontmgr_ohos",
+ "//third_party/flutter:ace_fontmgr_standard",
+ "//third_party/flutter:ace_skcms",
+ "//third_party/flutter:ace_png",
+ "//third_party/flutter:ace_libpng",
+ "//third_party/flutter:ace_jpeg",
+ "//third_party/flutter:ace_libjpeg",
+ "//third_party/flutter:ace_webp",
+ "//third_party/flutter:ace_libwebp",
+ "//third_party/flutter:ace_skia_opts",
+ "//third_party/flutter:ace_typeface_freetype",
+ "//third_party/flutter:ace_skia_ohos",
+ "//third_party/flutter:ace_libfreetype2",
+ "//third_party/flutter:ace_fontconfig.json",
+ "//third_party/flutter:ace_jsoncpp",
+ "//utils/native/base:utils",
+
+ ]
+ } else {
+ include_dirs += [ "//utils/native/base/include" ]
+ deps = [
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+ "//utils/native/base:utils",
+ ]
+
+# external_deps = [ "hilog:libhilog" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+# aosp_deps = [ "shared_library:libhwui" ]
+ }
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
+
+ohos_prebuilt_etc("rawpluginmetadata") {
+ source = "rawplugin.pluginmeta"
+ relative_install_dir = "multimediaplugin/image"
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/librawplugin/include/raw_decoder.h b/adapter/frameworks/librawplugin/include/raw_decoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..7348d251c6862b824428bcd2db9b87f19a9a65fa
--- /dev/null
+++ b/adapter/frameworks/librawplugin/include/raw_decoder.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 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 RAW_DECODER_H
+#define RAW_DECODER_H
+
+#include
+#include
+#include "SkCodec.h"
+#include "abs_image_decoder.h"
+#include "raw_stream.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "plugin_class_base.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+enum class RawDecodingState : int32_t {
+ UNDECIDED = 0,
+ SOURCE_INITED = 1,
+ BASE_INFO_PARSED = 2,
+ IMAGE_DECODING = 3,
+ IMAGE_ERROR = 4,
+ IMAGE_DECODED = 5
+};
+
+class RawDecoder : public AbsImageDecoder, public OHOS::MultimediaPlugin::PluginClassBase {
+public:
+ RawDecoder() = default;
+ virtual ~RawDecoder() override{};
+ void SetSource(InputDataStream &sourceStream) override;
+ void Reset() override;
+ uint32_t SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info) override;
+ uint32_t Decode(uint32_t index, DecodeContext &context) override;
+ uint32_t GetImageSize(uint32_t index, PlSize &size) override;
+ uint32_t PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context) override;
+ uint32_t GetImagePropertyString(uint32_t index, const std::string &key, std::string &value) override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(RawDecoder);
+ bool DecodeHeader();
+ PlAlphaType ConvertToAlphaType(SkAlphaType alphaType);
+ SkColorType ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat);
+ uint32_t AllocateMemory(SkImageInfo dstInfo, DecodeContext &context);
+ std::string ConvertEncodedFormatToString(SkEncodedImageFormat format);
+ InputDataStream *stream_ = nullptr;
+ std::unique_ptr codec_ = nullptr;
+ SkImageInfo info_;
+ SkColorType desireColor_ = kUnknown_SkColorType;
+ RawDecodingState state_ = RawDecodingState::UNDECIDED;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // RAW_DECODER_H
diff --git a/adapter/frameworks/librawplugin/include/raw_stream.h b/adapter/frameworks/librawplugin/include/raw_stream.h
new file mode 100644
index 0000000000000000000000000000000000000000..160d8f34eedf3582794be6b7194380de6b2e0d19
--- /dev/null
+++ b/adapter/frameworks/librawplugin/include/raw_stream.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 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 RAW_STREAM_H
+#define RAW_STREAM_H
+
+#include
+#include
+#include "SkStream.h"
+#include "hilog/log.h"
+#include "input_data_stream.h"
+#include "log_tags.h"
+#include "nocopyable.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+class RawStream : public SkStream {
+public:
+ RawStream() = default;
+ explicit RawStream(InputDataStream *stream);
+ virtual ~RawStream() override{};
+ /**
+ * Reads or skips size number of bytes.
+ * if buffer is null, skip size bytes, return how many bytes skipped.
+ * else copy size bytes into buffer, return how many bytes copied.
+ */
+ size_t read(void *buffer, size_t size) override;
+ /**
+ * Peeks size number of bytes.
+ */
+ size_t peek(void *buffer, size_t size) const override;
+ /**
+ * Returns true when all the bytes in the stream have been read.
+ */
+ bool isAtEnd() const override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(RawStream);
+ ImagePlugin::InputDataStream *inputStream_ = nullptr;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // RAW_STREAM_H
\ No newline at end of file
diff --git a/adapter/frameworks/librawplugin/rawplugin.pluginmeta b/adapter/frameworks/librawplugin/rawplugin.pluginmeta
new file mode 100755
index 0000000000000000000000000000000000000000..69a92dfc9deb56e096a23296069baf062db3f249
--- /dev/null
+++ b/adapter/frameworks/librawplugin/rawplugin.pluginmeta
@@ -0,0 +1,25 @@
+{
+ "packageName":"LibRawPlugin",
+ "version":"1.0.0.0",
+ "targetVersion":"1.0.0.0",
+ "libraryPath":"librawplugin.z.so",
+ "classes": [
+ {
+ "className":"OHOS::ImagePlugin::RawDecoder",
+ "services": [
+ {
+ "interfaceID":2,
+ "serviceType":0
+ }
+ ],
+ "priority":100,
+ "capabilities": [
+ {
+ "name":"encodeFormat",
+ "type":"string",
+ "value": "image/x-raw"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapter/frameworks/librawplugin/src/plugin_export.cpp b/adapter/frameworks/librawplugin/src/plugin_export.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e5089318abd117313f81530ea57655c9f2ec4050
--- /dev/null
+++ b/adapter/frameworks/librawplugin/src/plugin_export.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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 "plugin_export.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "plugin_utils.h"
+#include "raw_decoder.h"
+
+// plugin package name same as metadata.
+PLUGIN_EXPORT_REGISTER_PACKAGE("LibRawPlugin")
+
+// register implement classes of this plugin.
+PLUGIN_EXPORT_REGISTER_CLASS_BEGIN
+PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::RawDecoder)
+PLUGIN_EXPORT_REGISTER_CLASS_END
+
+using namespace OHOS::HiviewDFX;
+
+static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibRawPlugin" };
+
+#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__);
+#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__);
+
+// define the external interface of this plugin.
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_START()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE()
diff --git a/adapter/frameworks/librawplugin/src/raw_decoder.cpp b/adapter/frameworks/librawplugin/src/raw_decoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1087f98dd1cfeabdab698d13c192eb1c5f2f18f1
--- /dev/null
+++ b/adapter/frameworks/librawplugin/src/raw_decoder.cpp
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2021 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 "raw_decoder.h"
+#include "media_errors.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+using namespace Media;
+using namespace std;
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "RawDecoder" };
+namespace {
+constexpr uint32_t RAW_IMAGE_NUM = 1;
+}
+
+void RawDecoder::SetSource(InputDataStream &sourceStream)
+{
+ stream_ = &sourceStream;
+ state_ = RawDecodingState::SOURCE_INITED;
+}
+
+void RawDecoder::Reset()
+{
+ if (stream_ != nullptr) {
+ stream_->Seek(0);
+ }
+ codec_.release();
+ info_.reset();
+ desireColor_ = kUnknown_SkColorType;
+}
+
+uint32_t RawDecoder::GetImageSize(uint32_t index, PlSize &size)
+{
+ if (index >= RAW_IMAGE_NUM) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid index:%{public}u, range:%{public}u", index, RAW_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < RawDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid state:%{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= RawDecodingState::BASE_INFO_PARSED) {
+ size.width = info_.width();
+ size.height = info_.height();
+ return SUCCESS;
+ }
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ size.width = info_.width();
+ size.height = info_.height();
+ state_ = RawDecodingState::BASE_INFO_PARSED;
+ return SUCCESS;
+}
+
+uint32_t RawDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info)
+{
+ if (index >= RAW_IMAGE_NUM) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid index:%{public}u, range:%{public}u", index,
+ RAW_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < RawDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= RawDecodingState::IMAGE_DECODING) {
+ Reset();
+ state_ = RawDecodingState::SOURCE_INITED;
+ }
+ if (state_ < RawDecodingState::BASE_INFO_PARSED) {
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ state_ = RawDecodingState::BASE_INFO_PARSED;
+ }
+ PlPixelFormat desiredFormat = opts.desiredPixelFormat;
+ desireColor_ = ConvertToColorType(desiredFormat, info.pixelFormat);
+ info.size.width = info_.width();
+ info.size.height = info_.height();
+ info.alphaType = ConvertToAlphaType(info_.alphaType());
+ state_ = RawDecodingState::IMAGE_DECODING;
+ return SUCCESS;
+}
+
+uint32_t RawDecoder::AllocateMemory(SkImageInfo dstInfo, DecodeContext &context)
+{
+ size_t rowBytes = dstInfo.width() * dstInfo.bytesPerPixel();
+ uint64_t byteCount = static_cast(dstInfo.height()) * rowBytes;
+ if (context.allocatorType == Media::AllocatorType::SHARE_MEM_ALLOC) {
+#ifndef _WIN32
+ int fd = AshmemCreate("Common RawData", byteCount);
+ if (fd < 0) {
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
+ if (result < 0) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ void *ptr = ::mmap(nullptr, byteCount, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ context.pixelsBuffer.buffer = ptr;
+ void *fdBuffer = new int32_t();
+ if (fdBuffer == nullptr) {
+ HiLog::Error(LABEL, "new fdBuffer fail");
+ ::munmap(ptr, byteCount);
+ ::close(fd);
+ context.pixelsBuffer.buffer = nullptr;
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ *static_cast(fdBuffer) = fd;
+ context.pixelsBuffer.context = fdBuffer;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
+ context.freeFunc = nullptr;
+#endif
+ } else {
+ void *outputBuffer = malloc(byteCount);
+ if (outputBuffer == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, alloc output buffer size:[%{public}llu] error",
+ static_cast(byteCount));
+ return ERR_IMAGE_MALLOC_ABNORMAL;
+ }
+#ifdef _WIN32
+ memset(outputBuffer, 0, byteCount);
+#else
+ if (memset_s(outputBuffer, byteCount, 0, byteCount) != EOK) {
+ HiLog::Error(LABEL, "Decode failed, memset buffer failed");
+ free(outputBuffer);
+ outputBuffer = nullptr;
+ return ERR_IMAGE_MALLOC_ABNORMAL;
+ }
+#endif
+ context.pixelsBuffer.buffer = outputBuffer;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.pixelsBuffer.context = nullptr;
+ context.allocatorType = AllocatorType::HEAP_ALLOC;
+ context.freeFunc = nullptr;
+ }
+ return SUCCESS;
+}
+
+uint32_t RawDecoder::Decode(uint32_t index, DecodeContext &context)
+{
+ HiLog::Error(LABEL, "Decode begin");
+ if (index >= RAW_IMAGE_NUM) {
+ HiLog::Error(LABEL, "Decode failed, invalid index:%{public}u, range:%{public}u", index, RAW_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (codec_ == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, codec is null");
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+ if (state_ != RawDecodingState::IMAGE_DECODING) {
+ HiLog::Error(LABEL, "Decode failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ SkImageInfo dstInfo = info_.makeColorType(desireColor_);
+ size_t rowBytes = dstInfo.width() * dstInfo.bytesPerPixel();
+ if (context.pixelsBuffer.buffer == nullptr) {
+ uint32_t resultCode = AllocateMemory(dstInfo, context);
+ if (resultCode != SUCCESS) {
+ return resultCode;
+ }
+ }
+ HiLog::Error(LABEL, "AllocateMemory end");
+ uint8_t *dstBuffer = static_cast(context.pixelsBuffer.buffer);
+ SkCodec::Result ret = codec_->getPixels(dstInfo, dstBuffer, rowBytes);
+ if (ret != SkCodec::kSuccess) {
+ HiLog::Error(LABEL, "Decode failed, get pixels failed, ret=%{public}d", ret);
+ state_ = RawDecodingState::IMAGE_ERROR;
+ return ERR_IMAGE_DECODE_ABNORMAL;
+ }
+ state_ = RawDecodingState::IMAGE_DECODED;
+ HiLog::Error(LABEL, "Decode end");
+ return SUCCESS;
+}
+
+uint32_t RawDecoder::PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context)
+{
+ // currently not support increment decode
+ return ERR_IMAGE_DATA_UNSUPPORT;
+}
+
+bool RawDecoder::DecodeHeader()
+{
+ HiLog::Error(LABEL, "DecodeHeader begin");
+ codec_ = SkCodec::MakeFromStream(make_unique(stream_));
+ if (codec_ == nullptr) {
+ HiLog::Error(LABEL, "create codec from stream failed");
+ return false;
+ }
+ info_ = codec_->getInfo();
+ HiLog::Error(LABEL, "DecodeHeader end");
+ return true;
+}
+
+string RawDecoder::ConvertEncodedFormatToString(SkEncodedImageFormat format)
+{
+ string mimeType;
+ switch (format) {
+ case SkEncodedImageFormat::kJPEG:
+ mimeType = "image/jpeg";
+ break;
+ case SkEncodedImageFormat::kDNG:
+ mimeType = "image/x-adobe-dng";
+ break;
+ default:
+ mimeType = "";
+ break;
+ }
+ return mimeType;
+}
+
+uint32_t RawDecoder::GetImagePropertyString(uint32_t index, const std::string &key, std::string &value)
+{
+ HiLog::Info(LABEL, "[GetImagePropertyString] enter raw plugin, key:%{public}s", key.c_str());
+ uint32_t errorCode = SUCCESS;
+
+ if (state_ < RawDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid state:%{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+
+ if (state_ < RawDecodingState::BASE_INFO_PARSED) {
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImagePropertyString failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ state_ = RawDecodingState::BASE_INFO_PARSED;
+ }
+
+ if (key == ACTUAL_IMAGE_ENCODED_FORMAT) {
+ SkEncodedImageFormat format = codec_->getEncodedFormat();
+ HiLog::Info(LABEL, "getEncodedFormat format %{public}d", format);
+ value = ConvertEncodedFormatToString(format);
+ if (value == "") {
+ HiLog::Error(LABEL, "getEncodedFormat error format %{public}d", format);
+ return ERR_IMAGE_DATA_UNSUPPORT;
+ }
+ } else {
+ HiLog::Error(LABEL, "[GetImagePropertyString]key(%{public}s) not supported", key.c_str());
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+
+ return errorCode;
+}
+
+PlAlphaType RawDecoder::ConvertToAlphaType(SkAlphaType alphaType)
+{
+ switch (alphaType) {
+ case kOpaque_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
+ case kPremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_PREMUL;
+ case kUnpremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
+ default:
+ HiLog::Error(LABEL, "known alpha type:%{public}d", alphaType);
+ break;
+ }
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
+}
+
+SkColorType RawDecoder::ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat)
+{
+ switch (format) {
+ case PlPixelFormat::BGRA_8888: {
+ outputFormat = PlPixelFormat::BGRA_8888;
+ return kBGRA_8888_SkColorType;
+ }
+ case PlPixelFormat::ALPHA_8: {
+ SkColorType colorType = info_.colorType();
+ if (colorType == kAlpha_8_SkColorType || (colorType == kGray_8_SkColorType && info_.isOpaque())) {
+ outputFormat = PlPixelFormat::ALPHA_8;
+ return kAlpha_8_SkColorType;
+ }
+ break;
+ }
+ case PlPixelFormat::RGB_565: {
+ if (info_.isOpaque()) {
+ outputFormat = PlPixelFormat::RGB_565;
+ return kRGB_565_SkColorType;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ HiLog::Debug(LABEL, "unsupport convert to format:%{public}d, set default RGBA", format);
+ outputFormat = PlPixelFormat::RGBA_8888;
+ return kRGBA_8888_SkColorType;
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/librawplugin/src/raw_stream.cpp b/adapter/frameworks/librawplugin/src/raw_stream.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7a9a770cecf034ed21343e4351685183a6e14c71
--- /dev/null
+++ b/adapter/frameworks/librawplugin/src/raw_stream.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 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 "raw_stream.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "RawStream" };
+RawStream::RawStream(InputDataStream *stream) : inputStream_(stream) {}
+
+size_t RawStream::read(void *buffer, size_t size)
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "read failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ size_t curPosition = static_cast(inputStream_->Tell());
+ if (!inputStream_->Seek(curPosition + size)) {
+ HiLog::Error(LABEL, "read failed, curpositon=%{public}zu, skip size=%{public}zu", curPosition, size);
+ return 0;
+ }
+ return size;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Read(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "read failed, desire read size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+size_t RawStream::peek(void *buffer, size_t size) const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "peek failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ HiLog::Error(LABEL, "peek failed, output buffer is null");
+ return 0;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Peek(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "peek failed, desire peek size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+bool RawStream::isAtEnd() const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "get stream status failed, inputStream_ is null.");
+ return false;
+ }
+ size_t size = inputStream_->GetStreamSize();
+ return (inputStream_->Tell() == size);
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/libskiaplugin/BUILD.gn b/adapter/frameworks/libskiaplugin/BUILD.gn
new file mode 100755
index 0000000000000000000000000000000000000000..609d19a2075a47a22e17e20ea394ce16fcdbeb67
--- /dev/null
+++ b/adapter/frameworks/libskiaplugin/BUILD.gn
@@ -0,0 +1,92 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+import("//foundation/multimedia/image_standard/ide/image_decode_config.gni")
+
+ohos_shared_library("skiaplugin") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/libskiaplugin/src/plugin_export.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libskiaplugin/src/skia_decoder.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libskiaplugin/src/skia_stream.cpp",
+ ]
+
+ include_dirs = [
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include/image",
+ "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libskiaplugin/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include",
+ ]
+ if (use_mingw_win) {
+ defines = image_decode_windows_defines
+ include_dirs += [
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "//foundation/multimedia/image_standard/mock/native/include/secure",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/win",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ "//third_party/flutter/skia/include/codec",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/include/core",
+
+ ]
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils_static",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static",
+ ]
+
+ libs = [ "//foundation/multimedia/image_standard/libskia.lib" ]
+ } else if (use_clang_mac) {
+ defines = image_decode_mac_defines
+ include_dirs += [
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/mac",
+ "//libs/android_libs/sdk/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ "//utils/native/base/include",
+ ]
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils_static",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static",
+ "//utils/native/base:utilsecurec",
+ ]
+ } else {
+ include_dirs += [ "//utils/native/base/include" ]
+ deps = [
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils:image_utils",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+ "//utils/native/base:utils",
+ ]
+
+ external_deps = [ "hilog:libhilog" ]
+ android_deps = [ "shared_library:libhwui" ]
+ }
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
+
+ohos_prebuilt_etc("skiapluginmetadata") {
+ source = "skiaplugin.pluginmeta"
+ relative_install_dir = "multimediaplugin/image"
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/libskiaplugin/include/skia_decoder.h b/adapter/frameworks/libskiaplugin/include/skia_decoder.h
new file mode 100755
index 0000000000000000000000000000000000000000..03f2a237490429fbb9c64e5c0910ed9116c10122
--- /dev/null
+++ b/adapter/frameworks/libskiaplugin/include/skia_decoder.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2021 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 SKIA_DECODER_H
+#define SKIA_DECODER_H
+
+
+#include
+#include
+#include "abs_image_decoder.h"
+#include "hilog/log.h"
+#include "image_type.h"
+#include "log_tags.h"
+#include "SkCodec.h"
+#include "SkAndroidCodec.h"
+#include "skia_stream.h"
+#include "plugin_class_base.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+enum class SkiaDecodingState : int32_t {
+ UNDECIDED = 0,
+ SOURCE_INITED = 1,
+ BASE_INFO_PARSED = 2,
+ IMAGE_DECODING = 3,
+ IMAGE_ERROR = 4,
+ IMAGE_DECODED = 5
+};
+class SkiaDecoder : public AbsImageDecoder, public OHOS::MultimediaPlugin::PluginClassBase {
+public:
+ SkiaDecoder() = default;
+ virtual ~SkiaDecoder() override {};
+ void SetSource(InputDataStream &sourceStream) override;
+ void Reset() override;
+ uint32_t SetDecodeOptions(uint32_t index, const PlDecodeOptions &opts, PlImageInfo &info) override;
+ uint32_t Decode(uint32_t index, DecodeContext &context) override;
+ uint32_t GetImageSize(uint32_t index, PlSize &size) override;
+ uint32_t PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context) override;
+ bool HasProperty(std::string key) override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(SkiaDecoder);
+ const std::string SKIA_DECODER = "SKIA_DECODER";
+ bool DecodeHeader();
+ PlAlphaType ConvertToAlphaType(SkAlphaType alphaType);
+ SkColorType ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat);
+ uint32_t AllocShareMemory(DecodeContext &context, uint64_t byteCount);
+ uint32_t AllocHeapBuffer(DecodeContext &context, uint64_t byteCount);
+ InputDataStream *stream_ = nullptr;
+ std::unique_ptr acodec_ = nullptr;
+ uint32_t sampleSize_ = 0;
+ SkImageInfo info_;
+ SkColorType desireColor_ = kUnknown_SkColorType;
+ SkiaDecodingState state_ = SkiaDecodingState::UNDECIDED;
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // SKIA_DECODER_H
diff --git a/adapter/frameworks/libskiaplugin/include/skia_stream.h b/adapter/frameworks/libskiaplugin/include/skia_stream.h
new file mode 100755
index 0000000000000000000000000000000000000000..41c175e59d902c9b0046af6c559e4c17cf9363f0
--- /dev/null
+++ b/adapter/frameworks/libskiaplugin/include/skia_stream.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2021 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 SKIA_STREAM_H
+#define SKIA_STREAM_H
+
+#include
+#include
+#include "SkStream.h"
+#include "hilog/log.h"
+#include "input_data_stream.h"
+#include "log_tags.h"
+#include "nocopyable.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+class SkiaStream : public SkStream {
+public:
+ SkiaStream() = default;
+ explicit SkiaStream(InputDataStream *stream);
+ virtual ~SkiaStream() override{};
+ /**
+ * Reads or skips size number of bytes.
+ * if buffer is null, skip size bytes, return how many bytes skipped.
+ * else copy size bytes into buffer, return how many bytes copied.
+ */
+ size_t read(void *buffer, size_t size) override;
+ /**
+ * Peeks size number of bytes.
+ */
+ size_t peek(void *buffer, size_t size) const override;
+ /**
+ * Returns true when all the bytes in the stream have been read.
+ */
+ bool isAtEnd() const override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(SkiaStream);
+ ImagePlugin::InputDataStream *inputStream_ = nullptr;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // SKIA_STREAM_H
\ No newline at end of file
diff --git a/adapter/frameworks/libskiaplugin/skiaplugin.pluginmeta b/adapter/frameworks/libskiaplugin/skiaplugin.pluginmeta
new file mode 100755
index 0000000000000000000000000000000000000000..ce42f5196b35d848644d0e4f9f2f7033712fb565
--- /dev/null
+++ b/adapter/frameworks/libskiaplugin/skiaplugin.pluginmeta
@@ -0,0 +1,25 @@
+{
+ "packageName":"LibSkiaPlugin",
+ "version":"1.0.0.0",
+ "targetVersion":"1.0.0.0",
+ "libraryPath":"libskiaplugin.z.so",
+ "classes": [
+ {
+ "className":"OHOS::ImagePlugin::SkiaDecoder",
+ "services": [
+ {
+ "interfaceID":2,
+ "serviceType":0
+ }
+ ],
+ "priority":100,
+ "capabilities": [
+ {
+ "name":"encodeFormat",
+ "type":"string",
+ "value": "image/x-skia"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapter/frameworks/libskiaplugin/src/plugin_export.cpp b/adapter/frameworks/libskiaplugin/src/plugin_export.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..0378d0fbe8cbfbffd4c087209e250d26d92410fc
--- /dev/null
+++ b/adapter/frameworks/libskiaplugin/src/plugin_export.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 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 "hilog/log.h"
+#include "log_tags.h"
+#include "plugin_export.h"
+#include "plugin_utils.h"
+#include "skia_decoder.h"
+
+// plugin package name same as metadata.
+PLUGIN_EXPORT_REGISTER_PACKAGE("LibSkiaPlugin")
+
+// register implement classes of this plugin.
+PLUGIN_EXPORT_REGISTER_CLASS_BEGIN
+PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::SkiaDecoder)
+PLUGIN_EXPORT_REGISTER_CLASS_END
+
+using namespace OHOS::HiviewDFX;
+
+static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "SkiaPlugin" };
+
+#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__);
+#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__);
+
+// define the external interface of this plugin.
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_START()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE()
diff --git a/adapter/frameworks/libskiaplugin/src/skia_decoder.cpp b/adapter/frameworks/libskiaplugin/src/skia_decoder.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..67826ee01440003c04f98d173c406bec063923a1
--- /dev/null
+++ b/adapter/frameworks/libskiaplugin/src/skia_decoder.cpp
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2021 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 "skia_decoder.h"
+#include "image_utils.h"
+#include "media_errors.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+using namespace Media;
+using namespace std;
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "SkiaDecoder" };
+namespace {
+constexpr uint32_t IMAGE_NUM = 1;
+}
+
+void SkiaDecoder::SetSource(InputDataStream &sourceStream)
+{
+ stream_ = &sourceStream;
+ state_ = SkiaDecodingState::SOURCE_INITED;
+}
+
+void SkiaDecoder::Reset()
+{
+ if (stream_ != nullptr) {
+ stream_->Seek(0);
+ }
+ acodec_.release();
+ info_.reset();
+ desireColor_ = kUnknown_SkColorType;
+}
+
+uint32_t SkiaDecoder::GetImageSize(uint32_t index, PlSize &size)
+{
+ if (index >= IMAGE_NUM) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid index:%{public}u, range:%{public}u", index, IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < SkiaDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid state:%{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= SkiaDecodingState::BASE_INFO_PARSED) {
+ size.width = info_.width();
+ size.height = info_.height();
+ return SUCCESS;
+ }
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ size.width = info_.width();
+ size.height = info_.height();
+ state_ = SkiaDecodingState::BASE_INFO_PARSED;
+ return SUCCESS;
+}
+
+uint32_t SkiaDecoder::SetDecodeOptions(uint32_t index, const PlDecodeOptions &opts, PlImageInfo &info)
+{
+ if (index >= IMAGE_NUM) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid index:%{public}u, range:%{public}u", index,
+ IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < SkiaDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= SkiaDecodingState::IMAGE_DECODING) {
+ Reset();
+ state_ = SkiaDecodingState::SOURCE_INITED;
+ }
+ if (state_ < SkiaDecodingState::BASE_INFO_PARSED) {
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ state_ = SkiaDecodingState::BASE_INFO_PARSED;
+ }
+ HiLog::Info(LABEL, "SetDecodeOptions sampleSize:%{public}d, degree:%{public}f",
+ opts.sampleSize, opts.rotateDegrees);
+ PlPixelFormat desiredFormat = opts.desiredPixelFormat;
+ sampleSize_ = opts.sampleSize;
+ desireColor_ = ConvertToColorType(desiredFormat, info.pixelFormat);
+ auto alphaType = info_.isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType;
+ // we need compute new info, compute sample dimensions
+ auto sampledDims = acodec_->getSampledDimensions(sampleSize_);
+ HiLog::Info(LABEL, "SetDecodeOptions sampledDims, width:%{public}d, height:%{public}d",
+ sampledDims.width(), sampledDims.height());
+ info_ = info_.makeColorType(desireColor_)
+ .makeWH(sampledDims.width(), sampledDims.height())
+ .makeAlphaType(alphaType);
+ info.size.width = info_.width();
+ info.size.height = info_.height();
+ info.alphaType = ConvertToAlphaType(info_.alphaType());
+ state_ = SkiaDecodingState::IMAGE_DECODING;
+ return SUCCESS;
+}
+
+bool SkiaDecoder::HasProperty(std::string key)
+{
+ if (key == SKIA_DECODER) {
+ return true;
+ }
+ return false;
+}
+
+uint32_t SkiaDecoder::AllocShareMemory(DecodeContext &context, uint64_t byteCount)
+{
+#if !defined(_WIN32) && !defined(_APPLE)
+ int fd = AshmemCreate("BMP RawData", byteCount);
+ if (fd < 0) {
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
+ if (result < 0) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ void* ptr = ::mmap(nullptr, byteCount, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ context.pixelsBuffer.buffer = ptr;
+ void *fdBuffer = new int32_t();
+ if (fdBuffer == nullptr) {
+ HiLog::Error(LABEL, "new fdBuffer fail");
+ ::munmap(ptr, byteCount);
+ ::close(fd);
+ context.pixelsBuffer.buffer = nullptr;
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ *static_cast(fdBuffer) = fd;
+ context.pixelsBuffer.context = fdBuffer;
+ context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.freeFunc = nullptr;
+#endif
+ return SUCCESS;
+}
+
+uint32_t SkiaDecoder::AllocHeapBuffer(DecodeContext &context, uint64_t byteCount)
+{
+ void *outputBuffer = malloc(byteCount);
+ if (outputBuffer == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, alloc failed!");
+ return ERR_IMAGE_MALLOC_ABNORMAL;
+ }
+#ifdef _WIN32
+ memset(outputBuffer, 0, byteCount);
+#else
+ if (memset_s(outputBuffer, byteCount, 0, byteCount) != EOK) {
+ free(outputBuffer);
+ outputBuffer = nullptr;
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+#endif
+ context.pixelsBuffer.buffer = outputBuffer;
+ context.pixelsBuffer.context = nullptr;
+ context.allocatorType = AllocatorType::HEAP_ALLOC;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.freeFunc = nullptr;
+ return SUCCESS;
+}
+
+uint32_t SkiaDecoder::Decode(uint32_t index, DecodeContext &context)
+{
+ if (index >= IMAGE_NUM) {
+ HiLog::Error(LABEL, "Decode failed, invalid index:%{public}u, range:%{public}u", index, IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (acodec_ == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, codec is null");
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+ if (state_ != SkiaDecodingState::IMAGE_DECODING) {
+ HiLog::Error(LABEL, "Decode failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+
+ SkImageInfo dstInfo = info_;
+ if (ImageUtils::CheckMulOverflow(dstInfo.width(), dstInfo.height(), dstInfo.bytesPerPixel())) {
+ HiLog::Error(LABEL, "Decode failed, width:%{public}d, height:%{public}d is too large",
+ dstInfo.width(), dstInfo.height());
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+
+ if (context.pixelsBuffer.buffer == nullptr) {
+ uint64_t byteCount = static_cast(dstInfo.height()) * dstInfo.width() * dstInfo.bytesPerPixel();
+ if (context.allocatorType == Media::AllocatorType::SHARE_MEM_ALLOC) {
+ if (AllocShareMemory(context, byteCount) != SUCCESS) {
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+ } else {
+ if (AllocHeapBuffer(context, byteCount) != SUCCESS) {
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+ }
+ }
+ uint8_t *dstBuffer = static_cast(context.pixelsBuffer.buffer);
+ size_t rowBytes = dstInfo.width() * dstInfo.bytesPerPixel();
+ SkAndroidCodec::AndroidOptions options;
+ options.fSampleSize = sampleSize_;
+ auto result = acodec_->getAndroidPixels(dstInfo, dstBuffer, rowBytes, &options);
+ if (result != SkCodec::kSuccess) {
+ HiLog::Error(LABEL, "Decode failed, get pixels failed, ret=%{public}d", result);
+ state_ = SkiaDecodingState::IMAGE_ERROR;
+ return ERR_IMAGE_DECODE_ABNORMAL;
+ }
+ state_ = SkiaDecodingState::IMAGE_DECODED;
+ return SUCCESS;
+}
+
+uint32_t SkiaDecoder::PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context)
+{
+ // currently not support increment decode
+ return ERR_IMAGE_DATA_UNSUPPORT;
+}
+
+bool SkiaDecoder::DecodeHeader()
+{
+ HiLog::Info(LABEL, "stream_->GetStreamType() %{public}d", stream_->GetStreamType());
+ if (stream_->GetStreamType() == ImagePlugin::BUFFER_SOURCE_TYPE) {
+ std::unique_ptr stream =
+ std::make_unique(stream_->GetDataPtr(), stream_->GetStreamSize(), false);
+ acodec_ = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromStream(std::move(stream)));
+ } else {
+ acodec_ = SkAndroidCodec::MakeFromCodec(SkCodec::MakeFromStream(make_unique(stream_)));
+ }
+ if (!acodec_) {
+ HiLog::Error(LABEL, "Could not create acodec_");
+ return false;
+ }
+ info_ = acodec_->getInfo();
+ return true;
+}
+
+PlAlphaType SkiaDecoder::ConvertToAlphaType(SkAlphaType alphaType)
+{
+ switch (alphaType) {
+ case kOpaque_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
+ case kPremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_PREMUL;
+ case kUnpremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
+ default:
+ HiLog::Error(LABEL, "known alpha type:%{public}d", alphaType);
+ break;
+ }
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
+}
+
+SkColorType SkiaDecoder::ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat)
+{
+ switch (format) {
+ case PlPixelFormat::UNKNOWN:
+ case PlPixelFormat::RGBA_8888: {
+ outputFormat = PlPixelFormat::RGBA_8888;
+ return kRGBA_8888_SkColorType;
+ }
+ case PlPixelFormat::BGRA_8888: {
+ outputFormat = PlPixelFormat::BGRA_8888;
+ return kBGRA_8888_SkColorType;
+ }
+ case PlPixelFormat::ALPHA_8: {
+ SkColorType colorType = info_.colorType();
+ if (colorType == kAlpha_8_SkColorType || (colorType == kGray_8_SkColorType && info_.isOpaque())) {
+ outputFormat = PlPixelFormat::ALPHA_8;
+ return kAlpha_8_SkColorType;
+ }
+ break;
+ }
+ case PlPixelFormat::RGB_565: {
+ if (info_.isOpaque()) {
+ outputFormat = PlPixelFormat::RGB_565;
+ return kRGB_565_SkColorType;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ HiLog::Debug(LABEL, "unsupport conver to format:%{public}d, set default RGBA", format);
+ outputFormat = PlPixelFormat::RGBA_8888;
+ return kRGBA_8888_SkColorType;
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/libskiaplugin/src/skia_stream.cpp b/adapter/frameworks/libskiaplugin/src/skia_stream.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..e95f27c2043fc772660d84376199511ce6996a8c
--- /dev/null
+++ b/adapter/frameworks/libskiaplugin/src/skia_stream.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 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 "skia_stream.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "SkiaStream" };
+
+SkiaStream::SkiaStream(InputDataStream *stream) : inputStream_(stream) {}
+
+size_t SkiaStream::read(void *buffer, size_t size)
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "read failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ size_t curPosition = static_cast(inputStream_->Tell());
+ if (!inputStream_->Seek(curPosition + size)) {
+ HiLog::Error(LABEL, "read failed, curpositon=%{public}zu, skip size=%{public}zu", curPosition, size);
+ return 0;
+ }
+ return size;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Read(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "read failed, desire read size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+size_t SkiaStream::peek(void *buffer, size_t size) const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "peek failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ HiLog::Error(LABEL, "peek failed, output buffer is null");
+ return 0;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Peek(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "peek failed, desire peek size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+bool SkiaStream::isAtEnd() const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "get stream status failed, inputStream_ is null.");
+ return false;
+ }
+ size_t size = inputStream_->GetStreamSize();
+ return (inputStream_->Tell() == size);
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/libwbmpplugin/BUILD.gn_old b/adapter/frameworks/libwbmpplugin/BUILD.gn_old
new file mode 100644
index 0000000000000000000000000000000000000000..a84e16a02cc94be7d5d0f1f563099a0918985d97
--- /dev/null
+++ b/adapter/frameworks/libwbmpplugin/BUILD.gn_old
@@ -0,0 +1,91 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+import("//foundation/multimedia/image_standard/ide/image_decode_config.gni")
+
+ohos_shared_library("wbmpplugin") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/libwbmpplugin/src/plugin_export.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libwbmpplugin/src/wbmp_decoder.cpp",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libwbmpplugin/src/wbmp_stream.cpp",
+ ]
+
+ include_dirs = [
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include",
+ "//foundation/multimedia/image_standard/plugins/manager/include/image",
+ "//foundation/multimedia/image_standard/plugins/manager/include/pluginbase",
+ "//foundation/multimedia/image_standard/adapter/frameworks/libwbmpplugin/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/frameworks/innerkitsimpl/utils/include",
+ "//third_party/flutter/skia/include/codec",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/include/core",
+ ]
+
+ if (use_mingw_win) {
+ defines = image_decode_windows_defines
+ include_dirs += [
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "//foundation/multimedia/image_standard/mock/native/include/secure",
+ #"${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec",
+ #"${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ #"${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/win",
+ #"${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ ]
+ deps = [
+ "//foundation/graphic/ide/libs/skia:skia",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static",
+ ]
+
+ #libs = [ "//foundation/multimedia/image_standard/libskia.lib" ]
+ } else if (use_clang_mac) {
+ defines = image_decode_mac_defines
+ include_dirs += [
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/codec",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/mac",
+ "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ "//utils/native/base/include",
+ ]
+ deps = [
+ "//foundation/graphic/ide/libs/skia:skia",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager_static",
+ "//utils/native/base:utilsecurec",
+ ]
+ } else {
+ include_dirs += [ "//utils/native/base/include" ]
+ deps = [
+ "//foundation/multimedia/image_standard/plugins/manager:pluginmanager",
+ "//utils/native/base:utils",
+ ]
+
+# external_deps = [ "hilog:libhilog" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+# aosp_deps = [ "shared_library:libhwui" ]
+ }
+
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
+
+ohos_prebuilt_etc("wbmppluginmetadata") {
+ source = "wbmpplugin.pluginmeta"
+ relative_install_dir = "multimediaplugin/image"
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/libwbmpplugin/include/wbmp_decoder.h b/adapter/frameworks/libwbmpplugin/include/wbmp_decoder.h
new file mode 100644
index 0000000000000000000000000000000000000000..65af4fb0c4d219a9d8efebc7edbd88a0ac9e97f5
--- /dev/null
+++ b/adapter/frameworks/libwbmpplugin/include/wbmp_decoder.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2021 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 WBMP_DECODER_H
+#define WBMP_DECODER_H
+
+#include
+#include
+#include "SkCodec.h"
+#include "abs_image_decoder.h"
+#include "wbmp_stream.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "plugin_class_base.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+enum class WbmpDecodingState : int32_t {
+ UNDECIDED = 0,
+ SOURCE_INITED = 1,
+ BASE_INFO_PARSED = 2,
+ IMAGE_DECODING = 3,
+ IMAGE_ERROR = 4,
+ IMAGE_DECODED = 5
+};
+
+class WbmpDecoder : public AbsImageDecoder, public OHOS::MultimediaPlugin::PluginClassBase {
+public:
+ WbmpDecoder() = default;
+ virtual ~WbmpDecoder() override{};
+ void SetSource(InputDataStream &sourceStream) override;
+ void Reset() override;
+ uint32_t SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info) override;
+ uint32_t Decode(uint32_t index, DecodeContext &context) override;
+ uint32_t GetImageSize(uint32_t index, PlSize &size) override;
+ uint32_t PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context) override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(WbmpDecoder);
+ bool DecodeHeader();
+ PlAlphaType ConvertToAlphaType(SkAlphaType alphaType);
+ SkColorType ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat);
+ uint32_t AllocateMemory(SkImageInfo dstInfo, DecodeContext &context);
+
+ InputDataStream *stream_ = nullptr;
+ std::unique_ptr codec_ = nullptr;
+ SkImageInfo info_;
+ SkColorType desireColor_ = kUnknown_SkColorType;
+ WbmpDecodingState state_ = WbmpDecodingState::UNDECIDED;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // WBMP_DECODER_H
diff --git a/adapter/frameworks/libwbmpplugin/include/wbmp_stream.h b/adapter/frameworks/libwbmpplugin/include/wbmp_stream.h
new file mode 100644
index 0000000000000000000000000000000000000000..a4dc791d9eef2769547f96e8875cfc54e739de0e
--- /dev/null
+++ b/adapter/frameworks/libwbmpplugin/include/wbmp_stream.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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 WBMP_STREAM_H
+#define WBMP_STREAM_H
+
+#include
+#include
+#include "SkStream.h"
+#include "hilog/log.h"
+#include "input_data_stream.h"
+#include "log_tags.h"
+#include "nocopyable.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+class WbmpStream : public SkStream {
+public:
+ WbmpStream() = default;
+ explicit WbmpStream(InputDataStream *stream);
+ virtual ~WbmpStream() override{};
+ /**
+ * Reads or skips size number of bytes.
+ * if buffer is null, skip size bytes, return how many bytes skipped.
+ * else copy size bytes into buffer, return how many bytes copied.
+ */
+ size_t read(void *buffer, size_t size) override;
+ /**
+ * Peeks size number of bytes.
+ */
+ size_t peek(void *buffer, size_t size) const override;
+ /**
+ * Returns true when all the bytes in the stream have been read.
+ */
+ bool isAtEnd() const override;
+
+private:
+ DISALLOW_COPY_AND_MOVE(WbmpStream);
+
+ ImagePlugin::InputDataStream *inputStream_ = nullptr;
+};
+} // namespace ImagePlugin
+} // namespace OHOS
+
+#endif // WBMP_STREAM_H
\ No newline at end of file
diff --git a/adapter/frameworks/libwbmpplugin/src/plugin_export.cpp b/adapter/frameworks/libwbmpplugin/src/plugin_export.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..984ea35ed1f355e5866186a8996e7d5a3a729eb4
--- /dev/null
+++ b/adapter/frameworks/libwbmpplugin/src/plugin_export.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2021 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 "plugin_export.h"
+#include "hilog/log.h"
+#include "log_tags.h"
+#include "plugin_utils.h"
+#include "wbmp_decoder.h"
+
+// plugin package name same as metadata.
+PLUGIN_EXPORT_REGISTER_PACKAGE("LibWbmpPlugin")
+
+// register implement classes of this plugin.
+PLUGIN_EXPORT_REGISTER_CLASS_BEGIN
+PLUGIN_EXPORT_REGISTER_CLASS(OHOS::ImagePlugin::WbmpDecoder)
+PLUGIN_EXPORT_REGISTER_CLASS_END
+
+using namespace OHOS::HiviewDFX;
+
+static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "LibWbmpPlugin" };
+
+#define PLUGIN_LOG_D(...) HiLog::Debug(LABEL, __VA_ARGS__);
+#define PLUGIN_LOG_E(...) HiLog::Error(LABEL, __VA_ARGS__);
+
+// define the external interface of this plugin.
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_START()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_STOP()
+PLUGIN_EXPORT_DEFAULT_EXTERNAL_CREATE()
diff --git a/adapter/frameworks/libwbmpplugin/src/wbmp_decoder.cpp b/adapter/frameworks/libwbmpplugin/src/wbmp_decoder.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..34c748ed7863eccced01daba15c3e70c8b38baea
--- /dev/null
+++ b/adapter/frameworks/libwbmpplugin/src/wbmp_decoder.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright (C) 2021 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 "wbmp_decoder.h"
+#include "media_errors.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+using namespace Media;
+using namespace std;
+
+namespace {
+constexpr uint32_t WBMP_IMAGE_NUM = 1;
+}
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "WbmpDecoder" };
+
+void WbmpDecoder::SetSource(InputDataStream &sourceStream)
+{
+ stream_ = &sourceStream;
+ state_ = WbmpDecodingState::SOURCE_INITED;
+}
+
+void WbmpDecoder::Reset()
+{
+ if (stream_ != nullptr) {
+ stream_->Seek(0);
+ }
+ codec_.release();
+ info_.reset();
+ desireColor_ = kUnknown_SkColorType;
+}
+
+uint32_t WbmpDecoder::GetImageSize(uint32_t index, PlSize &size)
+{
+ if (index >= WBMP_IMAGE_NUM) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid index:%{public}u, range:%{public}u", index, WBMP_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < WbmpDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "GetImageSize failed, invalid state:%{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= WbmpDecodingState::BASE_INFO_PARSED) {
+ size.width = info_.width();
+ size.height = info_.height();
+ return SUCCESS;
+ }
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ size.width = info_.width();
+ size.height = info_.height();
+ state_ = WbmpDecodingState::BASE_INFO_PARSED;
+ return SUCCESS;
+}
+
+uint32_t WbmpDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info)
+{
+ if (index >= WBMP_IMAGE_NUM) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid index:%{public}u, range:%{public}u", index,
+ WBMP_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (state_ < WbmpDecodingState::SOURCE_INITED) {
+ HiLog::Error(LABEL, "SetDecodeOptions failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ if (state_ >= WbmpDecodingState::IMAGE_DECODING) {
+ Reset();
+ state_ = WbmpDecodingState::SOURCE_INITED;
+ }
+ if (state_ < WbmpDecodingState::BASE_INFO_PARSED) {
+ if (!DecodeHeader()) {
+ HiLog::Error(LABEL, "GetImageSize failed, decode header failed, state=%{public}d", state_);
+ return ERR_IMAGE_DECODE_HEAD_ABNORMAL;
+ }
+ state_ = WbmpDecodingState::BASE_INFO_PARSED;
+ }
+ PlPixelFormat desiredFormat = opts.desiredPixelFormat;
+ desireColor_ = ConvertToColorType(desiredFormat, info.pixelFormat);
+ info.size.width = info_.width();
+ info.size.height = info_.height();
+ info.alphaType = ConvertToAlphaType(info_.alphaType());
+ state_ = WbmpDecodingState::IMAGE_DECODING;
+ return SUCCESS;
+}
+
+uint32_t WbmpDecoder::AllocateMemory(SkImageInfo dstInfo, DecodeContext &context)
+{
+ size_t rowBytes = dstInfo.width() * dstInfo.bytesPerPixel();
+ uint64_t byteCount = static_cast(dstInfo.height()) * rowBytes;
+ if (context.allocatorType == Media::AllocatorType::SHARE_MEM_ALLOC) {
+#if !defined(_WIN32) && !defined(_APPLE)
+ int fd = AshmemCreate("Wbmp RawData", byteCount);
+ if (fd < 0) {
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ int result = AshmemSetProt(fd, PROT_READ | PROT_WRITE);
+ if (result < 0) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ void* ptr = ::mmap(nullptr, byteCount, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (ptr == MAP_FAILED) {
+ ::close(fd);
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ context.pixelsBuffer.buffer = ptr;
+ void *fdBuffer = new int32_t();
+ if (fdBuffer == nullptr) {
+ HiLog::Error(LABEL, "new fdBuffer fail");
+ ::munmap(ptr, byteCount);
+ ::close(fd);
+ context.pixelsBuffer.buffer = nullptr;
+ return ERR_SHAMEM_DATA_ABNORMAL;
+ }
+ *static_cast(fdBuffer) = fd;
+ context.pixelsBuffer.context = fdBuffer;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.allocatorType = AllocatorType::SHARE_MEM_ALLOC;
+ context.freeFunc = nullptr;
+#endif
+ } else {
+ void *outputBuffer = malloc(byteCount);
+ if (outputBuffer == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, alloc output buffer size:[%{public}llu] error",
+ static_cast(byteCount));
+ return ERR_IMAGE_MALLOC_ABNORMAL;
+ }
+#ifdef _WIN32
+ memset(outputBuffer, 0, byteCount);
+#else
+ if (memset_s(outputBuffer, byteCount, 0, byteCount) != EOK) {
+ HiLog::Error(LABEL, "Decode failed, memset buffer failed");
+ free(outputBuffer);
+ outputBuffer = nullptr;
+ return ERR_IMAGE_MALLOC_ABNORMAL;
+ }
+#endif
+ context.pixelsBuffer.buffer = outputBuffer;
+ context.pixelsBuffer.bufferSize = byteCount;
+ context.pixelsBuffer.context = nullptr;
+ context.allocatorType = AllocatorType::HEAP_ALLOC;
+ context.freeFunc = nullptr;
+ }
+ return SUCCESS;
+}
+
+uint32_t WbmpDecoder::Decode(uint32_t index, DecodeContext &context)
+{
+ if (index >= WBMP_IMAGE_NUM) {
+ HiLog::Error(LABEL, "Decode failed, invalid index:%{public}u, range:%{public}u", index, WBMP_IMAGE_NUM);
+ return ERR_IMAGE_INVALID_PARAMETER;
+ }
+ if (codec_ == nullptr) {
+ HiLog::Error(LABEL, "Decode failed, codec is null");
+ return ERR_IMAGE_DECODE_FAILED;
+ }
+ if (state_ != WbmpDecodingState::IMAGE_DECODING) {
+ HiLog::Error(LABEL, "Decode failed, invalid state %{public}d", state_);
+ return ERR_MEDIA_INVALID_OPERATION;
+ }
+ SkImageInfo dstInfo = info_.makeColorType(desireColor_);
+ size_t rowBytes = dstInfo.width() * dstInfo.bytesPerPixel();
+ if (context.pixelsBuffer.buffer == nullptr) {
+ uint32_t resultCode = AllocateMemory(dstInfo, context);
+ if (resultCode != SUCCESS) {
+ return resultCode;
+ }
+ }
+ uint8_t *dstBuffer = static_cast(context.pixelsBuffer.buffer);
+ SkCodec::Result ret = codec_->getPixels(dstInfo, dstBuffer, rowBytes);
+ if (ret != SkCodec::kSuccess) {
+ HiLog::Error(LABEL, "Decode failed, get pixels failed, ret=%{public}d", ret);
+ state_ = WbmpDecodingState::IMAGE_ERROR;
+ return ERR_IMAGE_DECODE_ABNORMAL;
+ }
+ state_ = WbmpDecodingState::IMAGE_DECODED;
+ return SUCCESS;
+}
+
+uint32_t WbmpDecoder::PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &context)
+{
+ // currently not support increment decode
+ return ERR_IMAGE_DATA_UNSUPPORT;
+}
+
+bool WbmpDecoder::DecodeHeader()
+{
+ codec_ = SkCodec::MakeFromStream(make_unique(stream_));
+ if (codec_ == nullptr) {
+ HiLog::Error(LABEL, "create codec from stream failed");
+ return false;
+ }
+ info_ = codec_->getInfo();
+ return true;
+}
+
+PlAlphaType WbmpDecoder::ConvertToAlphaType(SkAlphaType alphaType)
+{
+ switch (alphaType) {
+ case kOpaque_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
+ case kPremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_PREMUL;
+ case kUnpremul_SkAlphaType:
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
+ default:
+ HiLog::Error(LABEL, "known alpha type:%{public}d", alphaType);
+ break;
+ }
+ return PlAlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
+}
+
+SkColorType WbmpDecoder::ConvertToColorType(PlPixelFormat format, PlPixelFormat &outputFormat)
+{
+ switch (format) {
+ case PlPixelFormat::BGRA_8888: {
+ outputFormat = PlPixelFormat::BGRA_8888;
+ return kBGRA_8888_SkColorType;
+ }
+ case PlPixelFormat::ALPHA_8: {
+ SkColorType colorType = info_.colorType();
+ if (colorType == kAlpha_8_SkColorType || (colorType == kGray_8_SkColorType && info_.isOpaque())) {
+ outputFormat = PlPixelFormat::ALPHA_8;
+ return kAlpha_8_SkColorType;
+ }
+ break;
+ }
+ case PlPixelFormat::RGB_565: {
+ if (info_.isOpaque()) {
+ outputFormat = PlPixelFormat::RGB_565;
+ return kRGB_565_SkColorType;
+ }
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ HiLog::Debug(LABEL, "unsupport conver to format:%{public}d, set default RGBA", format);
+ outputFormat = PlPixelFormat::RGBA_8888;
+ return kRGBA_8888_SkColorType;
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/libwbmpplugin/src/wbmp_stream.cpp b/adapter/frameworks/libwbmpplugin/src/wbmp_stream.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c9b2b78eb99d4c8079ef7f57e6be8a70aa2fc605
--- /dev/null
+++ b/adapter/frameworks/libwbmpplugin/src/wbmp_stream.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 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 "wbmp_stream.h"
+
+namespace OHOS {
+namespace ImagePlugin {
+using namespace OHOS::HiviewDFX;
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "WbmpStream" };
+WbmpStream::WbmpStream(InputDataStream *stream) : inputStream_(stream) {}
+
+size_t WbmpStream::read(void *buffer, size_t size)
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "read failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ size_t curPosition = static_cast(inputStream_->Tell());
+ if (!inputStream_->Seek(curPosition + size)) {
+ HiLog::Error(LABEL, "read failed, curpositon=%{public}zu, skip size=%{public}zu", curPosition, size);
+ return 0;
+ }
+ return size;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Read(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "read failed, desire read size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+size_t WbmpStream::peek(void *buffer, size_t size) const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "peek failed, inputStream_ is null");
+ return 0;
+ }
+ if (buffer == nullptr) {
+ HiLog::Error(LABEL, "peek failed, output buffer is null");
+ return 0;
+ }
+ uint32_t desireSize = static_cast(size);
+ uint32_t bufferSize = desireSize;
+ uint32_t readSize = desireSize;
+ if (!inputStream_->Peek(desireSize, static_cast(buffer), bufferSize, readSize)) {
+ HiLog::Error(LABEL, "peek failed, desire peek size=%{public}u", desireSize);
+ return 0;
+ }
+ return readSize;
+}
+
+bool WbmpStream::isAtEnd() const
+{
+ if (inputStream_ == nullptr) {
+ HiLog::Error(LABEL, "get stream status failed, inputStream_ is null.");
+ return false;
+ }
+ size_t size = inputStream_->GetStreamSize();
+ return (inputStream_->Tell() == size);
+}
+} // namespace ImagePlugin
+} // namespace OHOS
diff --git a/adapter/frameworks/libwbmpplugin/wbmpplugin.pluginmeta b/adapter/frameworks/libwbmpplugin/wbmpplugin.pluginmeta
new file mode 100755
index 0000000000000000000000000000000000000000..ee5de90a0a09118d87bfb9f531dde1c818e33d93
--- /dev/null
+++ b/adapter/frameworks/libwbmpplugin/wbmpplugin.pluginmeta
@@ -0,0 +1,25 @@
+{
+ "packageName":"LibWbmpPlugin",
+ "version":"1.0.0.0",
+ "targetVersion":"1.0.0.0",
+ "libraryPath":"libwbmpplugin.z.so",
+ "classes": [
+ {
+ "className":"OHOS::ImagePlugin::WbmpDecoder",
+ "services": [
+ {
+ "interfaceID":2,
+ "serviceType":0
+ }
+ ],
+ "priority":100,
+ "capabilities": [
+ {
+ "name":"encodeFormat",
+ "type":"string",
+ "value": "image/vnd.wap.wbmp"
+ }
+ ]
+ }
+ ]
+}
diff --git a/adapter/frameworks/pixelconverter/BUILD.gn b/adapter/frameworks/pixelconverter/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..9b6de22a6ebcfb02efbfe783dff28710ee85de76
--- /dev/null
+++ b/adapter/frameworks/pixelconverter/BUILD.gn
@@ -0,0 +1,253 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+import("//foundation/multimedia/image_standard/ide/image_decode_config.gni")
+
+config("pixelconvertadapter_public_config") {
+ visibility = [ ":*" ]
+ include_dirs = [
+ "//foundation/multimedia/utils/include",
+ "//foundation/multimedia/image_standard/interfaces/innerkits/include",
+ "//foundation/multimedia/image_standard/adapter/frameworks/pixelconverter/include",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ "//foundation/communication/ipc/utils/include",
+ "//foundation/multimedia/utils/lite/interfaces/kits",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/include/encode",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/src/ports",
+ "//third_party/flutter/skia/src/images",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/third_party/externals/freetype/include/freetype",
+ "//third_party/flutter/skia/include/private",
+ "//third_party/bounds_checking_function/include",
+# "//utils/jni/jnikit/include",
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/core",
+ ]
+
+ if (use_mingw_win) {
+ include_dirs += [
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/win",
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ "//foundation/communication/ipc/utils/include",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/include/encode",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/src/ports",
+ "//third_party/flutter/skia/src/images",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/third_party/externals/freetype/include/freetype",
+ "//third_party/bounds_checking_function/include",
+ ]
+ } else if (use_clang_mac) {
+ include_dirs += [
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config/mac",
+# "${asdk_dir}/static_library/${target_os}_${target_cpu}/include/external/skia/include/config",
+ "//foundation/multimedia/image_standard/mock/native/include",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/include/encode",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/src/ports",
+ "//third_party/flutter/skia/src/images",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/third_party/externals/freetype/include/freetype",
+ "//third_party/bounds_checking_function/include",
+ ]
+ } else {
+ include_dirs += [
+ "//utils/native/base/include",
+ "//foundation/communication/ipc/utils/include",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ "//third_party/flutter/skia/include/core",
+ "//third_party/flutter/skia/include/encode",
+ "//third_party/flutter/skia",
+ "//third_party/flutter/skia/src/ports/skia_ohos",
+ "//third_party/flutter/skia/src/ports",
+ "//third_party/flutter/skia/src/images",
+ "//third_party/expat/lib",
+ "//third_party/flutter/skia/include/private",
+ "//third_party/flutter/skia/third_party/externals/freetype/include/freetype",
+ "//third_party/bounds_checking_function/include",
+ ]
+ }
+}
+
+ohos_shared_library("pixelconvertadapter") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/pixelconverter/src/pixel_convert_adapter.cpp",
+ #"//foundation/multimedia/image_standard/adapter/frameworks/pixelconverter/src/pixel_map_jni_utils.cpp",
+ ]
+
+ public_configs = [ ":pixelconvertadapter_public_config" ]
+
+ if (use_mingw_win) {
+ defines = image_decode_windows_defines
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ "//third_party/flutter:ace_skia_core",
+ "//third_party/flutter:ace_skcms",
+ "//third_party/flutter:ace_fontmgr_windows",
+ "//third_party/flutter:ace_png",
+ "//third_party/flutter:ace_jpeg",
+ "//third_party/flutter:ace_libjpeg",
+ "//third_party/flutter:ace_webp",
+ "//third_party/flutter:ace_libwebp",
+ "//third_party/flutter:ace_libpng",
+ "//third_party/flutter:ace_typeface_freetype",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//base/hiviewdfx/hilog/interfaces/native/innerkits/include",
+ "//foundation/communication/ipc/utils/include",
+ "//utils/jni:utils_jnikit_win",
+ ]
+ } else if (use_clang_mac) {
+ defines = image_decode_mac_defines
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ "//third_party/flutter:ace_skia_core",
+ "//third_party/flutter:ace_skcms",
+ "//third_party/flutter:ace_fontmgr_mac",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//third_party/flutter:ace_png",
+ "//third_party/flutter:ace_libpng",
+ "//third_party/flutter:ace_jpeg",
+ "//third_party/flutter:ace_libjpeg",
+ "//third_party/flutter:ace_webp",
+ "//third_party/flutter:ace_libwebp",
+ "//third_party/flutter:ace_skia_opts",
+ "//third_party/flutter:ace_typeface_freetype",
+ #"//utils/jni:utils_jnikit_mac",
+ ]
+ } else {
+ #deps = [
+ # "//utils/jni:utils_jnikit",
+ # ]
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ #"//third_party/flutter/skia:skia",
+ "//third_party/flutter:ace_skia_core",
+ "//third_party/flutter:ace_skcms",
+ "//third_party/flutter:ace_fontmgr_ohos",
+ "//third_party/flutter:ace_fontmgr_standard",
+ "//third_party/flutter:ace_png",
+ "//third_party/flutter:ace_libpng",
+ "//third_party/flutter:ace_jpeg",
+ "//third_party/flutter:ace_libjpeg",
+ "//third_party/flutter:ace_webp",
+ "//third_party/flutter:ace_libwebp",
+ "//third_party/flutter:ace_skia_opts",
+ "//third_party/flutter:ace_typeface_freetype",
+ "//third_party/flutter:ace_libsfntly_ohos",
+ "//third_party/flutter:ace_libfreetype2",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ "//third_party/flutter:ace_fontconfig.json",
+ "//third_party/flutter:ace_jsoncpp",
+ "//utils/native/base:utils",
+ #"//utils/jni:utils_jnikit_mac",
+ ]
+
+ #aosp_deps = [ "shared_library:libhwui" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+ }
+
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
+
+ohos_static_library("pixelconvertadapter_static") {
+ sources = [
+ "//foundation/multimedia/image_standard/adapter/frameworks/pixelconverter/src/pixel_convert_adapter.cpp",
+ #"//foundation/multimedia/image_standard/adapter/frameworks/pixelconverter/src/pixel_map_jni_utils.cpp",
+ ]
+ public_configs = [ ":pixelconvertadapter_public_config" ]
+
+ if (use_mingw_win) {
+ defines = image_decode_windows_defines
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ "//third_party/flutter:ace_skia_core",
+ "//third_party/flutter:ace_skcms",
+ "//third_party/flutter:ace_fontmgr_windows",
+ "//third_party/flutter:ace_png",
+ "//third_party/flutter:ace_libpng",
+ "//third_party/flutter:ace_jpeg",
+ "//third_party/flutter:ace_libjpeg",
+ "//third_party/flutter:ace_webp",
+ "//third_party/flutter:ace_libwebp",
+ "//third_party/flutter:ace_skia_opts",
+ "//third_party/flutter:ace_typeface_freetype",
+ "//third_party/flutter:ace_skia_windows",
+ "//third_party/flutter:ace_libfreetype2",
+
+ #"//third_party/flutter/skia:skia",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ #"//utils/jni:utils_jnikit_win",
+ ]
+ } else if (use_clang_mac) {
+ defines = image_decode_mac_defines
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ "//third_party/flutter:ace_skia_core",
+ "//third_party/flutter:ace_skcms",
+ "//third_party/flutter:ace_fontmgr_mac",
+ "//third_party/flutter:ace_png",
+ "//third_party/flutter:ace_libpng",
+ "//third_party/flutter:ace_jpeg",
+ "//third_party/flutter:ace_libjpeg",
+ "//third_party/flutter:ace_webp",
+ "//third_party/flutter:ace_libwebp",
+ "//third_party/flutter:ace_skia_opts",
+ "//third_party/flutter:ace_typeface_freetype",
+ "//third_party/flutter:ace_skia_mac",
+ "//third_party/flutter:ace_libfreetype2",
+ #"//third_party/flutter/skia:skia",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ #"//utils/jni:utils_jnikit_mac",
+ ]
+ } else {
+ #deps = [ "//utils/jni:utils_jnikit" ]
+ deps = [
+ #"//foundation/graphic/ide/libs/skia:skia",
+ "//third_party/flutter:ace_skia_core",
+ "//third_party/flutter:ace_fontmgr_ohos",
+ "//third_party/flutter:ace_fontmgr_standard",
+ "//third_party/flutter:ace_skcms",
+ "//third_party/flutter:ace_png",
+ "//third_party/flutter:ace_libpng",
+ "//third_party/flutter:ace_jpeg",
+ "//third_party/flutter:ace_libjpeg",
+ "//third_party/flutter:ace_webp",
+ "//third_party/flutter:ace_libwebp",
+ "//third_party/flutter:ace_skia_opts",
+ "//third_party/flutter:ace_typeface_freetype",
+ "//third_party/flutter:ace_skia_ohos",
+ "//third_party/flutter:ace_libfreetype2",
+ "//third_party/flutter:ace_fontconfig.json",
+ "//third_party/flutter:ace_jsoncpp",
+ "//utils/native/base:utils",
+
+ #"//third_party/flutter/skia:skia",
+ "//foundation/multimedia/image_standard/mock/native:log_mock_static",
+ #"//utils/jni:utils_jnikit_mac",
+ ]
+
+ #aosp_deps = [ "shared_library:libhwui" ]
+ external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
+ }
+}
diff --git a/adapter/frameworks/pixelconverter/include/pixel_convert_adapter.h b/adapter/frameworks/pixelconverter/include/pixel_convert_adapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..c2958f5b1b2b1f7c2e89e7e25a432c0a2f876b87
--- /dev/null
+++ b/adapter/frameworks/pixelconverter/include/pixel_convert_adapter.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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 PIXEL_CONVERT_ADAPTER_H
+#define PIXEL_CONVERT_ADAPTER_H
+
+#include "hilog/log.h"
+#include "image_type.h"
+#include "log_tags.h"
+
+namespace OHOS {
+namespace Media {
+class PixelConvertAdapter {
+public:
+ static bool WritePixelsConvert(const void *srcPixels, uint32_t srcRowBytes, const ImageInfo &srcInfo,
+ void *dstPixels, const Position &dstPos, uint32_t dstRowBytes,
+ const ImageInfo &dstInfo);
+ static bool ReadPixelsConvert(const void *srcPixels, const Position &srcPos, uint32_t srcRowBytes,
+ const ImageInfo &srcInfo, void *dstPixels, uint32_t dstRowBytes,
+ const ImageInfo &dstInfo);
+ static bool EraseBitmap(const void *srcPixels, uint32_t srcRowBytes, const ImageInfo &srcInfo, uint32_t color);
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // PIXEL_CONVERT_ADAPTER_H
\ No newline at end of file
diff --git a/adapter/frameworks/pixelconverter/include/pixel_map_jni_utils.h b/adapter/frameworks/pixelconverter/include/pixel_map_jni_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..724c6744bb065b06bbee0fa1cb3b175a0dba3db1
--- /dev/null
+++ b/adapter/frameworks/pixelconverter/include/pixel_map_jni_utils.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2021 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 PIXEL_MAP_JNI_UTILS_H
+#define PIXEL_MAP_JNI_UTILS_H
+
+#include "hilog/log.h"
+#include "jkit_utils.h"
+#include "log_tags.h"
+
+namespace OHOS {
+namespace Media {
+class PixelMapJniUtilsAdapter {
+public:
+ static jarray GetBufferBaseArray(JNIEnv *env, jobject jbuffer);
+ static bool GetBufferBaseArrayOffset(JNIEnv *env, jobject jbuffer, jint &offset);
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // PIXEL_MAP_JNI_UTILS_H
\ No newline at end of file
diff --git a/adapter/frameworks/pixelconverter/src/pixel_convert_adapter.cpp b/adapter/frameworks/pixelconverter/src/pixel_convert_adapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8395dda723a23e865190369a725b7153ae377d9c
--- /dev/null
+++ b/adapter/frameworks/pixelconverter/src/pixel_convert_adapter.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2021 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 "pixel_convert_adapter.h"
+#include "include/core/SkBitmap.h"
+#include "include/core/SkCanvas.h"
+#include "include/core/SkColor.h"
+#include "include/core/SkColorSpace.h"
+#include "include/core/SkImageInfo.h"
+#include "include/core/SkPaint.h"
+#include "include/core/SkPixmap.h"
+#ifdef _WIN32
+#include
+#endif
+
+namespace OHOS {
+namespace Media {
+using namespace OHOS::HiviewDFX;
+
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "PixelConvertAdapter" };
+
+static SkColorType PixelFormatConvert(const PixelFormat &pixelFormat)
+{
+ SkColorType colorType;
+ switch (pixelFormat) {
+ case PixelFormat::BGRA_8888:
+ colorType = SkColorType::kBGRA_8888_SkColorType;
+ break;
+ case PixelFormat::RGBA_8888:
+ colorType = SkColorType::kRGBA_8888_SkColorType;
+ break;
+ case PixelFormat::RGB_565:
+ colorType = SkColorType::kRGB_565_SkColorType;
+ break;
+ case PixelFormat::ALPHA_8:
+ colorType = SkColorType::kAlpha_8_SkColorType;
+ break;
+ default:
+ colorType = SkColorType::kUnknown_SkColorType;
+ break;
+ }
+ return colorType;
+}
+
+bool PixelConvertAdapter::WritePixelsConvert(const void *srcPixels, uint32_t srcRowBytes, const ImageInfo &srcInfo,
+ void *dstPixels, const Position &dstPos, uint32_t dstRowBytes,
+ const ImageInfo &dstInfo)
+{
+ // basic valid check, other parameters valid check in writePixels method
+ if (srcPixels == nullptr || dstPixels == nullptr) {
+ HiLog::Error(LABEL, "src or dst pixels invalid.");
+ return false;
+ }
+ SkAlphaType srcAlphaType = static_cast(srcInfo.alphaType);
+ SkAlphaType dstAlphaType = static_cast(dstInfo.alphaType);
+ SkColorType srcColorType = PixelFormatConvert(srcInfo.pixelFormat);
+ SkColorType dstColorType = PixelFormatConvert(dstInfo.pixelFormat);
+ SkImageInfo srcImageInfo = SkImageInfo::Make(srcInfo.size.width, srcInfo.size.height, srcColorType, srcAlphaType);
+ SkImageInfo dstImageInfo = SkImageInfo::Make(dstInfo.size.width, dstInfo.size.height, dstColorType, dstAlphaType);
+
+ SkBitmap dstBitmap;
+ SkPixmap srcPixmap(srcImageInfo, srcPixels, srcRowBytes);
+ if (!dstBitmap.installPixels(dstImageInfo, dstPixels, dstRowBytes)) {
+ HiLog::Error(LABEL, "WritePixelsConvert dst bitmap install pixels failed.");
+ return false;
+ }
+ if (!dstBitmap.writePixels(srcPixmap, dstPos.x, dstPos.y)) {
+ HiLog::Error(LABEL, "WritePixelsConvert dst bitmap write pixels by source failed.");
+ return false;
+ }
+
+ return true;
+}
+
+bool PixelConvertAdapter::ReadPixelsConvert(const void *srcPixels, const Position &srcPos, uint32_t srcRowBytes,
+ const ImageInfo &srcInfo, void *dstPixels, uint32_t dstRowBytes,
+ const ImageInfo &dstInfo)
+{
+ // basic valid check, other parameters valid check in readPixels method
+ if (srcPixels == nullptr || dstPixels == nullptr) {
+ HiLog::Error(LABEL, "src or dst pixels invalid.");
+ return false;
+ }
+ SkAlphaType srcAlphaType = static_cast(srcInfo.alphaType);
+ SkAlphaType dstAlphaType = static_cast(dstInfo.alphaType);
+ SkColorType srcColorType = PixelFormatConvert(srcInfo.pixelFormat);
+ SkColorType dstColorType = PixelFormatConvert(dstInfo.pixelFormat);
+ SkImageInfo srcImageInfo = SkImageInfo::Make(srcInfo.size.width, srcInfo.size.height, srcColorType, srcAlphaType);
+ SkImageInfo dstImageInfo = SkImageInfo::Make(dstInfo.size.width, dstInfo.size.height, dstColorType, dstAlphaType);
+
+ SkBitmap srcBitmap;
+ if (!srcBitmap.installPixels(srcImageInfo, const_cast(srcPixels), srcRowBytes)) {
+ HiLog::Error(LABEL, "ReadPixelsConvert src bitmap install pixels failed.");
+ return false;
+ }
+ if (!srcBitmap.readPixels(dstImageInfo, dstPixels, dstRowBytes, srcPos.x, srcPos.y)) {
+ HiLog::Error(LABEL, "ReadPixelsConvert read dst pixels from source failed.");
+ return false;
+ }
+ return true;
+}
+
+bool PixelConvertAdapter::EraseBitmap(const void *srcPixels, uint32_t srcRowBytes, const ImageInfo &srcInfo,
+ uint32_t color)
+{
+ if (srcPixels == nullptr) {
+ HiLog::Error(LABEL, "srcPixels is null.");
+ return false;
+ }
+ SkAlphaType srcAlphaType = static_cast(srcInfo.alphaType);
+ SkColorType srcColorType = PixelFormatConvert(srcInfo.pixelFormat);
+ SkImageInfo srcImageInfo = SkImageInfo::Make(srcInfo.size.width, srcInfo.size.height, srcColorType, srcAlphaType);
+ SkBitmap srcBitmap;
+ if (!srcBitmap.installPixels(srcImageInfo, const_cast(srcPixels), srcRowBytes)) {
+ HiLog::Error(LABEL, "ReadPixelsConvert src bitmap install pixels failed.");
+ return false;
+ }
+ const SkColor4f skColor = SkColor4f::FromColor(color);
+ SkPaint paint;
+ paint.setColor4f(skColor, SkColorSpace::MakeSRGB().get());
+ paint.setBlendMode(SkBlendMode::kSrc);
+ SkCanvas canvas(srcBitmap);
+ canvas.drawPaint(paint);
+ return true;
+}
+} // namespace Media
+} // namespace OHOS
diff --git a/adapter/frameworks/pixelconverter/src/pixel_map_jni_utils.cpp b/adapter/frameworks/pixelconverter/src/pixel_map_jni_utils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c38c616d038ba004a3d5b61d5305c142ac75166
--- /dev/null
+++ b/adapter/frameworks/pixelconverter/src/pixel_map_jni_utils.cpp
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 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 "pixel_map_jni_utils.h"
+
+namespace OHOS {
+namespace Media {
+using namespace OHOS::HiviewDFX;
+
+static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "PixelMapJniUtilsAdapter"
+};
+
+jarray PixelMapJniUtilsAdapter::GetBufferBaseArray(JNIEnv *env, jobject jbuffer)
+{
+ jclass nioAccessClass = env->FindClass("java/nio/NIOAccess");
+ if (nioAccessClass == nullptr) {
+ HiLog::Error(LABEL, "GetNioBufferBaseArray nioAccessClass is null.");
+ return nullptr;
+ }
+ jmethodID getBaseArrayMethod =
+ env->GetStaticMethodID(nioAccessClass, "getBaseArray", "(Ljava/nio/Buffer;)Ljava/lang/Object;");
+ if (getBaseArrayMethod == nullptr) {
+ HiLog::Error(LABEL, "GetNioBufferBaseArray getBaseArrayMethod is null.");
+ env->DeleteLocalRef(nioAccessClass);
+ return nullptr;
+ }
+ jarray bufferArray = static_cast(env->CallStaticObjectMethod(nioAccessClass, getBaseArrayMethod, jbuffer));
+ env->DeleteLocalRef(nioAccessClass);
+ return bufferArray;
+}
+
+bool PixelMapJniUtilsAdapter::GetBufferBaseArrayOffset(JNIEnv *env, jobject jbuffer, jint &offset)
+{
+ jclass nioAccessClass = env->FindClass("java/nio/NIOAccess");
+ if (nioAccessClass == nullptr) {
+ HiLog::Error(LABEL, "GetNioBufferBaseArray nioAccessClass is null.");
+ return false;
+ }
+ jmethodID getOffsetMethod = env->GetStaticMethodID(nioAccessClass, "getBaseArrayOffset", "(Ljava/nio/Buffer;)I");
+ if (getOffsetMethod == nullptr) {
+ HiLog::Error(LABEL, "GetNioBufferBaseArray getOffsetMethod is null.");
+ env->DeleteLocalRef(nioAccessClass);
+ return false;
+ }
+ offset = env->CallStaticIntMethod(nioAccessClass, getOffsetMethod, jbuffer);
+ env->DeleteLocalRef(nioAccessClass);
+ return true;
+}
+} // namespace Media
+} // namespace OHOS
diff --git a/adapter/frameworks/receiver/BUILD.gn b/adapter/frameworks/receiver/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..7b092ed136c3296d8393f57de296f31ca93dbef7
--- /dev/null
+++ b/adapter/frameworks/receiver/BUILD.gn
@@ -0,0 +1,85 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+
+config("imagereceiver_adapter_private_config") {
+ visibility = [ ":*" ]
+ include_dirs = [
+ "//foundation/multimedia/image/adapter/frameworks/receiver/include/private",
+ ]
+}
+
+config("imagereceiver_adapter_config") {
+ visibility = [ ":*" ]
+ include_dirs = [
+ "//foundation/multimedia/image/adapter/frameworks/receiver/include/base",
+ "//foundation/multimedia/image/frameworks/innerkitsimpl/utils/include",
+ "//foundation/multimedia/image/interfaces/innerkits/include",
+ "//foundation/multimedia/utils/include",
+ "//utils/native/base/include",
+ "//utils/jni/jnikit/include",
+ ]
+}
+
+config("build_config") {
+ cflags = [
+ "-Wno-inconsistent-missing-override",
+ "-Wno-thread-safety-attributes",
+ ]
+}
+
+ohos_shared_library("imagereceiver_adapter") {
+ sources = [
+ "//foundation/multimedia/image/adapter/frameworks/receiver/src/image_receiver_adapter.cpp",
+ "//foundation/multimedia/image/adapter/frameworks/receiver/src/image_receiver_utils.cpp",
+ ]
+
+ deps = [
+ "//foundation/multimedia/utils:multimedia_utils",
+ "//utils/jni:utils_jnikit",
+ "//utils/native/base:utils",
+ ]
+
+ external_deps = [
+ "graphic:libagp",
+ "graphic:libagp_adapter",
+ "hilog:libhilog",
+ ]
+
+ configs = [ ":imagereceiver_adapter_private_config" ]
+
+ public_configs = [
+ ":imagereceiver_adapter_config",
+ ":build_config",
+ ]
+
+ aosp_deps = [
+ "shared_library:android.hardware.graphics.bufferqueue@1.0",
+ "shared_library:android.hardware.graphics.bufferqueue@2.0",
+ "shared_library:libbinder",
+ "shared_library:libcutils",
+ "shared_library:libgui",
+ "shared_library:libhidlbase",
+ "shared_library:libhidltransport",
+ "shared_library:liblog",
+ "shared_library:libmedia_jni_utils",
+ "shared_library:libmedia_omx",
+ "shared_library:libnativewindow",
+ "shared_library:libui",
+ "shared_library:libutils",
+ ]
+
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/frameworks/receiver/include/base/image_receiver_adapter.h b/adapter/frameworks/receiver/include/base/image_receiver_adapter.h
new file mode 100644
index 0000000000000000000000000000000000000000..13b565b0da2d8638255a9f81725f2cbf7e417667
--- /dev/null
+++ b/adapter/frameworks/receiver/include/base/image_receiver_adapter.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IMAGE_RECEIVER_ADAPTER_H
+#define IMAGE_RECEIVER_ADAPTER_H
+
+#include
+#include
+#include "hilog/log.h"
+#include "image_format.h"
+#include "image_receiver_utils.h"
+#include "image_type.h"
+#include "jkit_utils.h"
+#include "log_tags.h"
+#include "media_errors.h"
+
+namespace OHOS {
+namespace Media {
+// global jni class cache
+struct ImageReceiverCache {
+ jfieldID nativeContext;
+ jmethodID onEventFromNative; // callback
+} g_imageReceiverCache;
+
+struct ImageCache {
+ jfieldID nativeBuffer;
+ jfieldID timestamp;
+ jfieldID components;
+} g_imageCache;
+
+struct ComponentCache {
+ jclass clazz;
+ jmethodID constructor;
+} g_componentCache;
+
+struct SurfaceCache {
+ jclass clazz;
+ jmethodID constructor;
+} g_surfaceCache;
+
+class ImageReceiverAdapter {
+public:
+ ImageReceiverAdapter() = default;
+ ~ImageReceiverAdapter() = default;
+ static void InitImageReceiverContext(JNIEnv *env, jobject thiz, jobject weakThiz, jint width, jint height,
+ jint format, jint capacity, jlong usage);
+ static jboolean ReadNextImage(JNIEnv *env, jobject thiz, jobject image);
+ static void ReleaseFreeBuffers(JNIEnv *env, jobject thiz);
+ static void ReleaseReceiver(JNIEnv *env, jobject thiz);
+ static jint GetFormat(JNIEnv *env, jobject thiz, jint receiverFormat);
+ static Media::Size GetSize(JNIEnv *env, jobject thiz);
+ static jobjectArray GetComponents(JNIEnv *env, jobject thiz, jint componentNum, jint receiverFormat);
+ static void ReleaseImage(JNIEnv *env, jobject thiz, jobject imageReceiver);
+ static void CacheActiveClass(JNIEnv *env, jclass clazz);
+ static jobject GetSurface(JNIEnv *env, jobject thiz);
+
+private:
+ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "ImageReceiverAdapter"
+ };
+ static bool CacheImageClass(JNIEnv *env);
+ static bool CacheSurfaceClass(JNIEnv *env);
+ static ComponentType GetComponentType(int32_t receiverFormat, int32_t index);
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // IMAGE_RECEIVER_ADAPTER_H
\ No newline at end of file
diff --git a/adapter/frameworks/receiver/include/base/image_receiver_utils.h b/adapter/frameworks/receiver/include/base/image_receiver_utils.h
new file mode 100644
index 0000000000000000000000000000000000000000..ecb18a7fb8211a74283a7f47d4ba5086230e9cad
--- /dev/null
+++ b/adapter/frameworks/receiver/include/base/image_receiver_utils.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IMAGE_RECEIVER_UTILS_H
+#define IMAGE_RECEIVER_UTILS_H
+
+#include
+#include
+#include "hilog/log.h"
+#include "jkit_utils.h"
+#include "log_tags.h"
+#include "securec.h"
+
+namespace OHOS {
+namespace Media {
+class ImageReceiverUtils {
+public:
+ static bool LogWhenNull(void *obj, const std::string &msg);
+ static bool ThrowExceptionWhenNull(void *obj, JNIEnv *env, const std::string &msg);
+ static void ThrowException(JNIEnv *env, const std::string &msg);
+ static std::string GetFmtMsg(const char *fmt, ...);
+
+private:
+ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "ImageReceiverUtils"
+ };
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // IMAGE_RECEIVER_UTILS_H
\ No newline at end of file
diff --git a/adapter/frameworks/receiver/include/private/image_receiver_private.h b/adapter/frameworks/receiver/include/private/image_receiver_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..084e92be86a61b9f1339eb8a048e9cb6c8ba1848
--- /dev/null
+++ b/adapter/frameworks/receiver/include/private/image_receiver_private.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2019 The Android Open Source Project
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef IMAGE_RECEIVER_PRIVATE_H
+#define IMAGE_RECEIVER_PRIVATE_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include "agp_view/agp_ui_surface.h"
+#include "hilog/log.h"
+#include "image_format.h"
+#include "jkit_utils.h"
+#include "log_tags.h"
+#include "media_errors.h"
+#include "nocopyable.h"
+
+namespace OHOS {
+namespace Media {
+class ImageReceiverContext : public android::ConsumerBase::FrameAvailableListener {
+public:
+ ImageReceiverContext(JNIEnv *env, jobject weakThiz, jclass clazz, int32_t capacity);
+ virtual ~ImageReceiverContext();
+ virtual void onFrameAvailable(const android::BufferItem &item); // android virtual method
+ android::BufferItem *PopBufferItem();
+ void PushBufferItem(android::BufferItem *buffer);
+ void SetBufferConsumer(const android::sp &consumer)
+ {
+ bufferConsumer_ = consumer;
+ }
+ android::BufferItemConsumer *GetBufferConsumer()
+ {
+ return bufferConsumer_.get();
+ }
+ void SetProducer(const android::sp &producer)
+ {
+ bufferProducer_ = producer;
+ }
+ android::IGraphicBufferProducer *GetProducer()
+ {
+ return bufferProducer_.get();
+ }
+ void SetBufferFormat(int32_t format)
+ {
+ format_ = format;
+ }
+ int32_t GetBufferFormat() const
+ {
+ return format_;
+ }
+ void SetBufferDataspace(android_dataspace dataSpace)
+ {
+ dataSpace_ = dataSpace;
+ }
+ android_dataspace GetBufferDataspace() const
+ {
+ return dataSpace_;
+ }
+ void SetBufferWidth(int32_t width)
+ {
+ width_ = width;
+ }
+ int32_t GetBufferWidth() const
+ {
+ return width_;
+ }
+ void SetBufferHeight(int32_t height)
+ {
+ height_ = height;
+ }
+ int32_t GetBufferHeight() const
+ {
+ return height_;
+ }
+ DISALLOW_COPY_AND_MOVE(ImageReceiverContext);
+
+private:
+ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "ImageReceiverContext"
+ };
+ android::List buffers_;
+ android::sp bufferConsumer_;
+ android::sp bufferProducer_;
+ jobject weakThiz_;
+ jclass clazz_;
+ int32_t width_;
+ int32_t height_;
+ android_dataspace dataSpace_;
+ int32_t format_;
+};
+
+class ImageReceiverCommon {
+public:
+ ImageReceiverCommon() = default;
+ ~ImageReceiverCommon() = default;
+ static bool InitBufferConsumer(JNIEnv *env, android::sp context,
+ android::sp bufferConsumer,
+ android::String8 consumerName, jint width, jint height, int nativeFormat,
+ android_dataspace nativeDataspace);
+ static bool CheckNoOpaqueFormat(JNIEnv *env, android::sp context, android::BufferItem *buffer,
+ android::BufferItemConsumer *bufferConsumer);
+ static void SetNativeContext(JNIEnv *env, jobject thiz, android::sp context);
+ static ImageReceiverContext *GetImageReceiverContext(JNIEnv *env, jobject thiz);
+ static android::BufferItem *GetBufferItem(JNIEnv *env, jobject image);
+ static bool GetLockedImage(JNIEnv *env, jobject thiz, android::LockedImage *image);
+ static android::sp UnlockImageIfLocked(JNIEnv *env, jobject image);
+ static uint32_t GetProcessUniqueId();
+ // format transform
+ static android::PublicFormat ConvertReceiverFormatToAndroidPublic(int32_t receiverFormat);
+ static ImageFormat ConvertAndroidPublicToReceiverFormat(android::PublicFormat publicFormat);
+
+private:
+ static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {
+ LOG_CORE, LOG_TAG_DOMAIN_ID_IMAGE, "ImageReceiverCommon"
+ };
+};
+} // namespace Media
+} // namespace OHOS
+
+#endif // IMAGE_RECEIVER_PRIVATE_H
\ No newline at end of file
diff --git a/adapter/frameworks/receiver/src/image_receiver_adapter.cpp b/adapter/frameworks/receiver/src/image_receiver_adapter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..479b284a0c9293cd2b6393c945acbff437731b65
--- /dev/null
+++ b/adapter/frameworks/receiver/src/image_receiver_adapter.cpp
@@ -0,0 +1,693 @@
+/*
+ * Copyright (C) 2021 Huawei Device Co., Ltd.
+ * Copyright (C) 2019 The Android Open Source Project
+ * 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 "image_receiver_adapter.h"
+#include "image_receiver_private.h"
+
+namespace OHOS {
+namespace Media {
+static constexpr int32_t DEFAULT_SIZE = -1;
+static constexpr int32_t MAX_COMPONENT_NUM = 3;
+
+using namespace OHOS::HiviewDFX;
+
+void ImageReceiverAdapter::InitImageReceiverContext(JNIEnv *env, jobject thiz, jobject weakThiz, jint width,
+ jint height, jint format, jint capacity, jlong usage)
+{
+ HiLog::Debug(LABEL,
+ "width:%{public}d, height:%{public}d, format:%{public}d, capacity:%{public}d, "
+ "usage:%{public}ld.",
+ width, height, format, capacity, static_cast(usage));
+ android::PublicFormat publicFormat = ImageReceiverCommon::ConvertReceiverFormatToAndroidPublic(format);
+ int nativeFormat = android::mapPublicFormatToHalFormat(publicFormat);
+ android_dataspace nativeDataspace = android::mapPublicFormatToHalDataspace(publicFormat);
+ android::sp graphicProducer;
+ android::sp graphicConsumer;
+ android::BufferQueue::createBufferQueue(&graphicProducer, &graphicConsumer);
+ uint64_t consumerUsage = usage; // ImageReceiver default use HardwareBuffer::USAGE_CPU_READ_OFTEN
+ android::sp bufferConsumer =
+ new (std::nothrow) android::BufferItemConsumer(graphicConsumer, consumerUsage, capacity, true);
+ if (bufferConsumer == nullptr) {
+ std::string errMsg =
+ ImageReceiverUtils::GetFmtMsg("allocate cumsumer buffer(format:0x%x) failed.", nativeFormat);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return;
+ }
+ if (consumerUsage & GRALLOC_USAGE_PROTECTED) {
+ graphicConsumer->setConsumerIsProtected(true);
+ }
+ jclass receiverClazz = env->GetObjectClass(thiz);
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(receiverClazz, env, "get ImageReceiver class fail.")) {
+ return;
+ }
+ android::sp context(
+ new (std::nothrow)ImageReceiverContext(env, weakThiz, receiverClazz, capacity));
+ env->DeleteLocalRef(receiverClazz);
+ if (context == nullptr) {
+ ImageReceiverUtils::ThrowException(env, "allocate image receiver context memory error.");
+ return;
+ }
+ uint32_t uniqueId = ImageReceiverCommon::GetProcessUniqueId();
+ android::String8 consumerName = android::String8::format("ImageReceiver-%dx%df%xc%d-%d-%d", width, height, format,
+ capacity, getpid(), uniqueId);
+ if (!ImageReceiverCommon::InitBufferConsumer(env, context, bufferConsumer, consumerName, width, height,
+ nativeFormat, nativeDataspace)) {
+ HiLog::Error(LABEL, "init buffer consumer failed.");
+ return;
+ }
+ context->SetBufferConsumer(bufferConsumer);
+ context->SetProducer(graphicProducer);
+ context->SetBufferFormat(nativeFormat);
+ context->SetBufferDataspace(nativeDataspace);
+ context->SetBufferWidth(width);
+ context->SetBufferHeight(height);
+ ImageReceiverCommon::SetNativeContext(env, thiz, context);
+}
+
+jboolean ImageReceiverAdapter::ReadNextImage(JNIEnv *env, jobject thiz, jobject image)
+{
+ ImageReceiverContext *context = ImageReceiverCommon::GetImageReceiverContext(env, thiz);
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(context, env, "ImageReceiver is not initialized or was closed.")) {
+ return false;
+ }
+ android::BufferItem *buffer = context->PopBufferItem();
+ if (ImageReceiverUtils::LogWhenNull(buffer, "buffer item is null, maybe exceed maximum of buffers.")) {
+ return false;
+ }
+ android::BufferItemConsumer *bufferConsumer = context->GetBufferConsumer();
+ if (ImageReceiverUtils::LogWhenNull(bufferConsumer, "buffer consumer is null.")) {
+ return false;
+ }
+ int32_t ret = bufferConsumer->acquireBuffer(buffer, 0);
+ if (ret != SUCCESS) {
+ context->PushBufferItem(buffer);
+ if (ret != android::BufferQueue::NO_BUFFER_AVAILABLE) {
+ if (ret == android::INVALID_OPERATION) {
+ HiLog::Error(LABEL, "get image exceed maximum of buffers.");
+ } else {
+ std::string errMsg = ImageReceiverUtils::GetFmtMsg("get image occurs unknown error:%d.", ret);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ }
+ }
+ return false;
+ }
+ if (!ImageReceiverCommon::CheckNoOpaqueFormat(env, context, buffer, bufferConsumer)) {
+ HiLog::Error(LABEL, "check no opaque format failed.");
+ return false;
+ }
+ // set image instance member variables
+ env->SetLongField(image, g_imageCache.nativeBuffer, reinterpret_cast(buffer));
+ env->SetLongField(image, g_imageCache.timestamp, static_cast(buffer->mTimestamp));
+ return true;
+}
+
+void ImageReceiverAdapter::ReleaseFreeBuffers(JNIEnv *env, jobject thiz)
+{
+ ImageReceiverContext *context = ImageReceiverCommon::GetImageReceiverContext(env, thiz);
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(context, env, "ImageReceiver is not initialized or was closed.")) {
+ return;
+ }
+ android::BufferItemConsumer *bufferConsumer = context->GetBufferConsumer();
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(bufferConsumer, env, "consumer buffer item is null.")) {
+ return;
+ }
+ int32_t ret = bufferConsumer->discardFreeBuffers();
+ if (ret != SUCCESS) {
+ std::string errMsg = ImageReceiverUtils::GetFmtMsg("release free buffers failed:%d", ret);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ }
+}
+
+void ImageReceiverAdapter::CacheActiveClass(JNIEnv *env, jclass clazz)
+{
+ if (g_componentCache.clazz != nullptr && g_surfaceCache.clazz != nullptr) {
+ HiLog::Debug(LABEL, "global active class was initialized.");
+ return;
+ }
+ // ImageReceiver mapping
+ g_imageReceiverCache.nativeContext = env->GetFieldID(clazz, "nativeContext", "J");
+ if (ImageReceiverUtils::LogWhenNull(g_imageReceiverCache.nativeContext,
+ "can't find ImageReceiver.nativeContext.")) {
+ return;
+ }
+ g_imageReceiverCache.onEventFromNative =
+ env->GetStaticMethodID(clazz, "onEventFromNative", "(Ljava/lang/Object;)V");
+ if (ImageReceiverUtils::LogWhenNull(g_imageReceiverCache.onEventFromNative,
+ "can't find ImageReceiver.onEventFromNative.")) {
+ return;
+ }
+ if (!CacheImageClass(env)) {
+ HiLog::Error(LABEL, "cache image attribute failed.");
+ return;
+ }
+ if (!CacheSurfaceClass(env)) {
+ HiLog::Error(LABEL, "cache surface attribute failed.");
+ return;
+ }
+}
+
+bool ImageReceiverAdapter::CacheImageClass(JNIEnv *env)
+{
+ jclass imageClazz = env->FindClass("ohos/media/image/Image");
+ if (ImageReceiverUtils::LogWhenNull(imageClazz, "find Image class fail.")) {
+ return false;
+ }
+ g_imageCache.nativeBuffer = env->GetFieldID(imageClazz, "nativeBuffer", "J");
+ if (ImageReceiverUtils::LogWhenNull(g_imageCache.nativeBuffer, "can't find Image.nativeBuffer.")) {
+ env->DeleteLocalRef(imageClazz);
+ return false;
+ }
+ g_imageCache.timestamp = env->GetFieldID(imageClazz, "timestamp", "J");
+ if (ImageReceiverUtils::LogWhenNull(g_imageCache.timestamp, "can't find Image.timestamp.")) {
+ env->DeleteLocalRef(imageClazz);
+ return false;
+ }
+ g_imageCache.components = env->GetFieldID(imageClazz, "components", "[Lohos/media/image/Image$Component;");
+ if (ImageReceiverUtils::LogWhenNull(g_imageCache.components, "can't find Image.component.")) {
+ env->DeleteLocalRef(imageClazz);
+ return false;
+ }
+ // Image$Component constructor mapping
+ jclass componentClazz = env->FindClass("ohos/media/image/Image$Component");
+ if (ImageReceiverUtils::LogWhenNull(componentClazz, "can't find Image$Component class.")) {
+ env->DeleteLocalRef(imageClazz);
+ return false;
+ }
+ g_componentCache.constructor = env->GetMethodID(componentClazz, "", "(IIILjava/nio/ByteBuffer;)V");
+ if (ImageReceiverUtils::LogWhenNull(g_componentCache.constructor, "can't find Component constructor.")) {
+ env->DeleteLocalRef(imageClazz);
+ env->DeleteLocalRef(componentClazz);
+ return false;
+ }
+ env->DeleteLocalRef(imageClazz);
+ g_componentCache.clazz = reinterpret_cast(env->NewGlobalRef(componentClazz));
+ return true;
+}
+
+bool ImageReceiverAdapter::CacheSurfaceClass(JNIEnv *env)
+{
+ // Surface constructor mapping
+ jclass surfaceClazz = env->FindClass("ohos/agp/graphics/Surface");
+ if (ImageReceiverUtils::LogWhenNull(surfaceClazz, "can't find Surface class.")) {
+ return false;
+ }
+ g_surfaceCache.constructor = env->GetMethodID(surfaceClazz, "", "(J)V");
+ if (ImageReceiverUtils::LogWhenNull(g_surfaceCache.constructor, "can't find Surface constructor.")) {
+ env->DeleteLocalRef(surfaceClazz);
+ return false;
+ }
+ g_surfaceCache.clazz = reinterpret_cast(env->NewGlobalRef(surfaceClazz));
+ return true;
+}
+
+jobject ImageReceiverAdapter::GetSurface(JNIEnv *env, jobject thiz)
+{
+ ImageReceiverContext *context = ImageReceiverCommon::GetImageReceiverContext(env, thiz);
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(context, env, "ImageReceiver is not initialized or was closed.")) {
+ return nullptr;
+ }
+ android::IGraphicBufferProducer *graphicProducer = context->GetProducer();
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(graphicProducer, env, "graphic buffer producer is null.")) {
+ return nullptr;
+ }
+ const android::sp &bufferProducer = graphicProducer;
+ AGP::UISurface *zSurface = new (std::nothrow) AGP::UISurface(bufferProducer, true);
+ if (zSurface == nullptr) {
+ HiLog::Error(LABEL, "create surface pointer fail.");
+ return nullptr;
+ }
+ jobject surfaceObj =
+ env->NewObject(g_surfaceCache.clazz, g_surfaceCache.constructor, reinterpret_cast(zSurface));
+ if (ImageReceiverUtils::LogWhenNull(surfaceObj, "create surface jni class fail.")) {
+ delete zSurface;
+ zSurface = nullptr;
+ return nullptr;
+ }
+ return surfaceObj;
+}
+
+void ImageReceiverAdapter::ReleaseReceiver(JNIEnv *env, jobject thiz)
+{
+ ImageReceiverContext *context = ImageReceiverCommon::GetImageReceiverContext(env, thiz);
+ if (ImageReceiverUtils::LogWhenNull(context, "ImageReceiver is not initialized or was closed.")) {
+ return;
+ }
+ android::BufferItemConsumer *consumer = context->GetBufferConsumer();
+ if (consumer != nullptr) {
+ consumer->abandon();
+ consumer->setFrameAvailableListener(nullptr);
+ }
+ ImageReceiverCommon::SetNativeContext(env, thiz, nullptr);
+}
+
+jint ImageReceiverAdapter::GetFormat(JNIEnv *env, jobject thiz, jint receiverFormat)
+{
+ android::PublicFormat publicFormat = ImageReceiverCommon::ConvertReceiverFormatToAndroidPublic(receiverFormat);
+ if (android::isFormatOpaque(static_cast(publicFormat))) {
+ return static_cast(ImageFormat::UNKNOWN);
+ }
+ int32_t nativeFormat = android::mapPublicFormatToHalFormat(publicFormat);
+ android::BufferItem *buffer = ImageReceiverCommon::GetBufferItem(env, thiz);
+ if (ImageReceiverUtils::LogWhenNull(buffer, "image buffer item is null.")) {
+ return static_cast(ImageFormat::UNKNOWN);
+ }
+ int32_t actualFormat = android::applyFormatOverrides(buffer->mGraphicBuffer->getPixelFormat(), nativeFormat);
+ // override the image format to HAL_PIXEL_FORMAT_YCbCr_420_888 if the actual format is NV21 or YV12.
+ if (android::isPossiblyYUV(actualFormat)) {
+ actualFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
+ }
+ android::PublicFormat publicFmt = android::mapHalFormatDataspaceToPublicFormat(actualFormat, buffer->mDataSpace);
+ ImageFormat imageFmt = ImageReceiverCommon::ConvertAndroidPublicToReceiverFormat(publicFmt);
+ return static_cast(imageFmt);
+}
+
+Media::Size ImageReceiverAdapter::GetSize(JNIEnv *env, jobject thiz)
+{
+ Size size;
+ android::BufferItem *buffer = ImageReceiverCommon::GetBufferItem(env, thiz);
+ if (ImageReceiverUtils::LogWhenNull(buffer, "image buffer item is null.")) {
+ return size;
+ }
+ size.width = android::getBufferWidth(buffer);
+ size.height = android::getBufferHeight(buffer);
+ return size;
+}
+
+jobjectArray ImageReceiverAdapter::GetComponents(JNIEnv *env, jobject thiz, jint componentNum, jint receiverFormat)
+{
+ android::PublicFormat publicFormat = ImageReceiverCommon::ConvertReceiverFormatToAndroidPublic(receiverFormat);
+ int32_t nativeFormat = android::mapPublicFormatToHalFormat(publicFormat);
+ if (android::isFormatOpaque(nativeFormat) && componentNum > 0) {
+ std::string errMsg = ImageReceiverUtils::GetFmtMsg("format 0x%x is opaque, components number %d must be 0",
+ nativeFormat, componentNum);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return nullptr;
+ }
+ jobjectArray components = env->NewObjectArray(componentNum, g_componentCache.clazz, nullptr);
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(components, env, "create components array failed.")) {
+ return nullptr;
+ }
+ if (android::isFormatOpaque(nativeFormat)) {
+ return components; // opaque components size is 0
+ }
+ android::LockedImage lockedImage = android::LockedImage();
+ if (!ImageReceiverCommon::GetLockedImage(env, thiz, &lockedImage)) {
+ env->DeleteLocalRef(components);
+ return nullptr;
+ }
+
+ int32_t rowStride = 0;
+ int32_t pixelStride = 0;
+ uint8_t *dataPtr = nullptr;
+ uint32_t dataSize = 0;
+ jobject byteBuffer = nullptr;
+ for (int32_t index = 0; index < componentNum; index++) {
+ int32_t ret = android::getLockedImageInfo(&lockedImage, index, nativeFormat, &dataPtr, &dataSize, &pixelStride,
+ &rowStride);
+ if (ret != SUCCESS) {
+ env->DeleteLocalRef(components);
+ HiLog::Error(LABEL, "get lock image info error:%{public}d", ret);
+ return nullptr;
+ }
+ byteBuffer = env->NewDirectByteBuffer(dataPtr, dataSize);
+ if (byteBuffer == nullptr) {
+ env->DeleteLocalRef(components);
+ ImageReceiverUtils::ThrowException(env, "allocate byte buffer failed, maybe memory not enough.");
+ return nullptr;
+ }
+ int32_t componentType = static_cast(GetComponentType(receiverFormat, index));
+ jobject component = env->NewObject(g_componentCache.clazz, g_componentCache.constructor, componentType,
+ rowStride, pixelStride, byteBuffer);
+ env->SetObjectArrayElement(components, index, component);
+ env->DeleteLocalRef(component);
+ env->DeleteLocalRef(byteBuffer);
+ }
+ return components;
+}
+
+void ImageReceiverAdapter::ReleaseImage(JNIEnv *env, jobject thiz, jobject imageReceiver)
+{
+ ImageReceiverContext *context = ImageReceiverCommon::GetImageReceiverContext(env, imageReceiver);
+ if (ImageReceiverUtils::LogWhenNull(context, "maybe ImageReceiver#release called before Image#release.")) {
+ return;
+ }
+ android::BufferItem *buffer = ImageReceiverCommon::GetBufferItem(env, thiz);
+ if (ImageReceiverUtils::LogWhenNull(buffer, "image buffer item is null.")) {
+ return;
+ }
+ android::sp releaseFence = ImageReceiverCommon::UnlockImageIfLocked(env, thiz);
+ android::BufferItemConsumer *bufferConsumer = context->GetBufferConsumer();
+ if (ImageReceiverUtils::LogWhenNull(buffer, "image buffer consumer is null.")) {
+ return;
+ }
+ bufferConsumer->releaseBuffer(*buffer, releaseFence);
+ env->SetLongField(thiz, g_imageCache.nativeBuffer, reinterpret_cast(nullptr));
+ context->PushBufferItem(buffer);
+ HiLog::Debug(LABEL, "image (format:0x%{public}x) has been released.", context->GetBufferFormat());
+}
+
+ComponentType ImageReceiverAdapter::GetComponentType(int32_t receiverFormat, int32_t index)
+{
+ ImageFormat imageFormat = static_cast(receiverFormat);
+ ComponentType result = ComponentType::UNKNOWN;
+ switch (imageFormat) {
+ case ImageFormat::NV21:
+ case ImageFormat::YUV420_888:
+ if (index >= MAX_COMPONENT_NUM) {
+ break;
+ }
+ result = (index == 0) ? ComponentType::YUV_Y : ((index == 1) ? ComponentType::YUV_U : ComponentType::YUV_V);
+ break;
+ case ImageFormat::JPEG:
+ result = (index == 0) ? ComponentType::JPEG : ComponentType::UNKNOWN;
+ break;
+ case ImageFormat::RAW10:
+ result = (index == 0) ? ComponentType::RAW10 : ComponentType::UNKNOWN;
+ break;
+ case ImageFormat::RAW16:
+ result = (index == 0) ? ComponentType::RAW16 : ComponentType::UNKNOWN;
+ break;
+ case ImageFormat::H264:
+ result = (index == 0) ? ComponentType::H264 : ComponentType::UNKNOWN;
+ break;
+ case ImageFormat::H265:
+ result = (index == 0) ? ComponentType::H265 : ComponentType::UNKNOWN;
+ break;
+ default:
+ HiLog::Error(LABEL, "unknown image format:%d", receiverFormat);
+ break;
+ }
+ return result;
+}
+
+ImageReceiverContext::ImageReceiverContext(JNIEnv *env, jobject weakThiz, jclass clazz, int32_t capacity)
+{
+ weakThiz_ = env->NewGlobalRef(weakThiz);
+ clazz_ = reinterpret_cast(env->NewGlobalRef(clazz));
+ format_ = static_cast(ImageFormat::UNKNOWN);
+ dataSpace_ = HAL_DATASPACE_UNKNOWN;
+ width_ = DEFAULT_SIZE;
+ height_ = DEFAULT_SIZE;
+ for (int32_t i = 0; i < capacity; i++) {
+ android::BufferItem *buffer = new (std::nothrow) android::BufferItem;
+ if (buffer == nullptr) {
+ HiLog::Error(LABEL, "allocate buffer item %{public}d memory error.", i);
+ continue;
+ }
+ buffers_.push_back(buffer);
+ }
+}
+
+ImageReceiverContext::~ImageReceiverContext()
+{
+ Jkit jkit;
+ JNIEnv *jniEnv = jkit.Get();
+ if (jniEnv != nullptr) {
+ jniEnv->DeleteGlobalRef(weakThiz_);
+ jniEnv->DeleteGlobalRef(clazz_);
+ } else {
+ HiLog::Warn(LABEL, "leaking jni global object references.");
+ }
+ // delete buffer items
+ for (android::List::iterator iter = buffers_.begin(); iter != buffers_.end(); ++iter) {
+ delete *iter;
+ *iter = nullptr;
+ }
+ buffers_.clear();
+ if (bufferConsumer_ != nullptr) {
+ bufferConsumer_.clear();
+ }
+ bufferConsumer_ = nullptr;
+}
+
+// android virtual method
+void ImageReceiverContext::onFrameAvailable(const android::BufferItem &item)
+{
+ Jkit jkit;
+ JNIEnv *jniEnv = jkit.Get();
+ if (jniEnv != nullptr) {
+ jniEnv->CallStaticVoidMethod(clazz_, g_imageReceiverCache.onEventFromNative, weakThiz_);
+ HiLog::Debug(LABEL, "onFrameAvailable event post success.");
+ } else {
+ HiLog::Warn(LABEL, "onFrameAvailable event will not post cause by jniEnv is null.");
+ }
+}
+
+android::BufferItem *ImageReceiverContext::PopBufferItem()
+{
+ if (buffers_.empty()) {
+ return nullptr;
+ }
+ // return a buffer item and remove it from the list
+ android::List::iterator iter = buffers_.begin();
+ android::BufferItem *buffer = *iter;
+ buffers_.erase(iter);
+ return buffer;
+}
+
+void ImageReceiverContext::PushBufferItem(android::BufferItem *buffer)
+{
+ // clear the graphic buffer and push buffer item back to the list
+ buffer->mGraphicBuffer = nullptr;
+ buffers_.push_back(buffer);
+}
+
+bool ImageReceiverCommon::InitBufferConsumer(JNIEnv *env, android::sp context,
+ android::sp bufferConsumer,
+ android::String8 consumerName, jint width, jint height, int nativeFormat,
+ android_dataspace nativeDataspace)
+{
+ bufferConsumer->setName(consumerName);
+ bufferConsumer->setFrameAvailableListener(context);
+ int32_t ret = bufferConsumer->setDefaultBufferSize(width, height);
+ if (ret != SUCCESS) {
+ std::string errMsg = ImageReceiverUtils::GetFmtMsg("set format 0x%x default buffer size:[%d, %d] failed:%d.",
+ nativeFormat, width, height, ret);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return false;
+ }
+ ret = bufferConsumer->setDefaultBufferFormat(nativeFormat);
+ if (ret != SUCCESS) {
+ std::string errMsg =
+ ImageReceiverUtils::GetFmtMsg("set default buffer format 0x%x failed:%d.", nativeFormat, ret);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return false;
+ }
+ ret = bufferConsumer->setDefaultBufferDataSpace(nativeDataspace);
+ if (ret != SUCCESS) {
+ std::string errMsg =
+ ImageReceiverUtils::GetFmtMsg("set default buffer data space 0x%x failed:%d.", nativeDataspace, ret);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return false;
+ }
+ return true;
+}
+
+bool ImageReceiverCommon::CheckNoOpaqueFormat(JNIEnv *env, android::sp context,
+ android::BufferItem *buffer, android::BufferItemConsumer *bufferConsumer)
+{
+ if (!android::isFormatOpaque(context->GetBufferFormat())) {
+ android::Point point = buffer->mCrop.leftTop();
+ if (point.x != 0 || point.y != 0) {
+ std::string errMsg =
+ ImageReceiverUtils::GetFmtMsg("crop left top [%d, %d] must to be at origin", point.x, point.y);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return false;
+ }
+ // check producer buffer settings is same as image receiver settings
+ int32_t producerWidth = getBufferWidth(buffer);
+ int32_t producerHeight = getBufferHeight(buffer);
+ int32_t producerFormat = buffer->mGraphicBuffer->getPixelFormat();
+ int32_t receiverWidth = context->GetBufferWidth();
+ int32_t receiverHeight = context->GetBufferHeight();
+ int32_t receiverFormat = context->GetBufferFormat();
+ if ((producerFormat != HAL_PIXEL_FORMAT_BLOB) && (receiverFormat != HAL_PIXEL_FORMAT_BLOB) &&
+ (producerWidth != receiverWidth || producerHeight != receiverHeight)) {
+ HiLog::Debug(LABEL,
+ "producer size [%{public}d, %{public}d] mismatch receiver size [%{public}d, "
+ "%{public}d]",
+ producerWidth, producerHeight, receiverWidth, receiverHeight);
+ }
+ if (producerFormat != receiverFormat) {
+ if (receiverFormat == HAL_PIXEL_FORMAT_YCbCr_420_888 && android::isPossiblyYUV(producerFormat)) {
+ HiLog::Debug(LABEL, "treat producer format 0x%{public}x as HAL_PIXEL_FORMAT_YCbCr_420_888.",
+ producerFormat);
+ } else if (receiverFormat == HAL_PIXEL_FORMAT_BLOB && producerFormat == HAL_PIXEL_FORMAT_RGBA_8888) {
+ HiLog::Debug(LABEL, "receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.");
+ } else {
+ bufferConsumer->releaseBuffer(*buffer);
+ context->PushBufferItem(buffer);
+ std::string errMsg = ImageReceiverUtils::GetFmtMsg("producer format:0x%x mismatch receiver format:0x%x",
+ producerFormat, receiverFormat);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+void ImageReceiverCommon::SetNativeContext(JNIEnv *env, jobject thiz, android::sp context)
+{
+ if (context != nullptr) {
+ context->incStrong(reinterpret_cast(SetNativeContext));
+ env->SetLongField(thiz, g_imageReceiverCache.nativeContext, reinterpret_cast(context.get()));
+ } else {
+ ImageReceiverContext *ctx = GetImageReceiverContext(env, thiz);
+ if (ctx != nullptr) {
+ ctx->decStrong(reinterpret_cast(SetNativeContext));
+ env->SetLongField(thiz, g_imageReceiverCache.nativeContext, reinterpret_cast(nullptr));
+ }
+ }
+}
+
+ImageReceiverContext *ImageReceiverCommon::GetImageReceiverContext(JNIEnv *env, jobject thiz)
+{
+ ImageReceiverContext *context =
+ reinterpret_cast(env->GetLongField(thiz, g_imageReceiverCache.nativeContext));
+ return context;
+}
+
+bool ImageReceiverCommon::GetLockedImage(JNIEnv *env, jobject thiz, android::LockedImage *image)
+{
+ android::BufferItem *buffer = GetBufferItem(env, thiz);
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(buffer, env, "lock image buffer item is null.")) {
+ return false;
+ }
+ int fenceFd = buffer->mFence->dup();
+ int32_t ret = android::lockImageFromBuffer(buffer, GRALLOC_USAGE_SW_READ_OFTEN, fenceFd, image);
+ if (ret != SUCCESS) {
+ ::close(fenceFd);
+ std::string errMsg = ImageReceiverUtils::GetFmtMsg("lock image buffer (format:0x%x) failed:%d",
+ buffer->mGraphicBuffer->getPixelFormat(), ret);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return false;
+ }
+ // assignment
+ image->crop = buffer->mCrop;
+ image->timestamp = buffer->mTimestamp;
+ image->dataSpace = buffer->mDataSpace;
+ image->frameNumber = buffer->mFrameNumber;
+ return true;
+}
+
+android::sp ImageReceiverCommon::UnlockImageIfLocked(JNIEnv *env, jobject image)
+{
+ android::BufferItem *buffer = GetBufferItem(env, image);
+ if (ImageReceiverUtils::ThrowExceptionWhenNull(buffer, env, "unlock image buffer item is null.")) {
+ return android::Fence::NO_FENCE;
+ }
+ bool isBufferLocked = false;
+ jobject components = nullptr;
+ if (!android::isFormatOpaque(buffer->mGraphicBuffer->getPixelFormat())) {
+ components = env->GetObjectField(image, g_imageCache.components);
+ }
+ isBufferLocked = (components != nullptr);
+ if (isBufferLocked) {
+ int32_t fenceFd = -1;
+ int32_t ret = buffer->mGraphicBuffer->unlockAsync(&fenceFd);
+ if (ret != SUCCESS) {
+ std::string errMsg = ImageReceiverUtils::GetFmtMsg("async unlock buffer failed:%d", ret);
+ ImageReceiverUtils::ThrowException(env, errMsg);
+ return android::Fence::NO_FENCE;
+ }
+ android::sp releaseFence = new (std::nothrow) android::Fence(fenceFd);
+ if (releaseFence == nullptr) {
+ HiLog::Error(LABEL, "allocate releaseFence memory error.");
+ }
+ return releaseFence;
+ }
+ return android::Fence::NO_FENCE;
+}
+
+android::BufferItem *ImageReceiverCommon::GetBufferItem(JNIEnv *env, jobject image)
+{
+ return reinterpret_cast(env->GetLongField(image, g_imageCache.nativeBuffer));
+}
+
+uint32_t ImageReceiverCommon::GetProcessUniqueId()
+{
+ static volatile int32_t g_Counter = 0;
+ return android_atomic_inc(&g_Counter);
+}
+
+// only mapping several formats supported by ImageFormat at present
+android::PublicFormat ImageReceiverCommon::ConvertReceiverFormatToAndroidPublic(int32_t receiverFormat)
+{
+ android::PublicFormat result = android::PublicFormat::UNKNOWN;
+ ImageFormat imageFormat = static_cast(receiverFormat);
+ switch (imageFormat) {
+ case ImageFormat::NV21:
+ result = android::PublicFormat::NV21;
+ break;
+ case ImageFormat::YUV420_888:
+ result = android::PublicFormat::YUV_420_888;
+ break;
+ case ImageFormat::JPEG:
+ result = android::PublicFormat::JPEG;
+ break;
+ case ImageFormat::RAW10:
+ result = android::PublicFormat::RAW10;
+ break;
+ case ImageFormat::RAW16:
+ result = android::PublicFormat::RAW_SENSOR;
+ break;
+ case ImageFormat::H264:
+ result = android::PublicFormat::H264;
+ break;
+ case ImageFormat::H265:
+ result = android::PublicFormat::H265;
+ break;
+ default:
+ result = android::PublicFormat::UNKNOWN;
+ break;
+ }
+ return result;
+}
+
+ImageFormat ImageReceiverCommon::ConvertAndroidPublicToReceiverFormat(android::PublicFormat publicFormat)
+{
+ ImageFormat result = ImageFormat::UNKNOWN;
+ switch (publicFormat) {
+ case android::PublicFormat::NV21:
+ result = ImageFormat::NV21;
+ break;
+ case android::PublicFormat::YUV_420_888:
+ result = ImageFormat::YUV420_888;
+ break;
+ case android::PublicFormat::JPEG:
+ result = ImageFormat::JPEG;
+ break;
+ case android::PublicFormat::RAW10:
+ result = ImageFormat::RAW10;
+ break;
+ case android::PublicFormat::RAW_SENSOR:
+ result = ImageFormat::RAW16;
+ break;
+ case android::PublicFormat::H264:
+ result = ImageFormat::H264;
+ break;
+ case android::PublicFormat::H265:
+ result = ImageFormat::H265;
+ break;
+ default:
+ result = ImageFormat::UNKNOWN;
+ break;
+ }
+ return result;
+}
+} // namespace Media
+} // namespace OHOS
diff --git a/adapter/frameworks/receiver/src/image_receiver_utils.cpp b/adapter/frameworks/receiver/src/image_receiver_utils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b6451f1078c06505898991ff08fc967085fb8e24
--- /dev/null
+++ b/adapter/frameworks/receiver/src/image_receiver_utils.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2021 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 "image_receiver_utils.h"
+
+namespace OHOS {
+namespace Media {
+static constexpr uint32_t ERR_MSG_BUFFER_SIZE = 256;
+
+using namespace OHOS::HiviewDFX;
+
+bool ImageReceiverUtils::LogWhenNull(void *obj, const std::string &msg)
+{
+ if (obj != nullptr) {
+ return false;
+ }
+ if (!msg.empty()) {
+ HiLog::Error(LABEL, "%{public}s", msg.c_str());
+ }
+ return true;
+}
+
+bool ImageReceiverUtils::ThrowExceptionWhenNull(void *obj, JNIEnv *env, const std::string &msg)
+{
+ if (obj != nullptr) {
+ return false;
+ }
+ ThrowException(env, msg);
+ return true;
+}
+
+void ImageReceiverUtils::ThrowException(JNIEnv *env, const std::string &msg)
+{
+ if (!msg.empty()) {
+ HiLog::Error(LABEL, "%{public}s", msg.c_str());
+ JkitThrowIllegalStateException(env, msg.c_str());
+ }
+}
+
+std::string ImageReceiverUtils::GetFmtMsg(const char *fmt, ...)
+{
+ char buffer[ERR_MSG_BUFFER_SIZE] = { 0 };
+ va_list args;
+ va_start(args, fmt);
+ int32_t ret = vsnprintf_s(buffer, ERR_MSG_BUFFER_SIZE, (ERR_MSG_BUFFER_SIZE - 1), fmt, args);
+ if (ret <= 0) {
+ HiLog::Error(LABEL, "fail to build format error message:%{public}d", ret);
+ }
+ va_end(args);
+ std::string result = buffer;
+ return result;
+}
+} // namespace Media
+} // namespace OHOS
\ No newline at end of file
diff --git a/adapter/hals/jpegdec/BUILD.gn b/adapter/hals/jpegdec/BUILD.gn
new file mode 100644
index 0000000000000000000000000000000000000000..1aba118a93e731baa24b395e5c0657e09470ac1b
--- /dev/null
+++ b/adapter/hals/jpegdec/BUILD.gn
@@ -0,0 +1,53 @@
+# Copyright (C) 2021 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("//build/ohos.gni")
+
+config("jpegdec_public_config") {
+ visibility = [ ":*" ]
+ include_dirs =
+ [ "//foundation/multimedia/image_standard/adapter/hals/jpegdec/include" ]
+}
+
+ohos_shared_library("jpegdec") {
+ sources = [
+ "src/vendor/huawei/hardware/jpegdec/1.0/JpegDecodeAll.cpp",
+ "src/vendor/huawei/hardware/jpegdec/1.0/types.cpp",
+ ]
+
+ defines = [ "_USING_LIBCXX" ]
+
+ include_dirs = [ "include" ]
+
+ public_configs = [ ":jpegdec_public_config" ]
+
+ if (is_clang) {
+ cflags = [
+ "-Wno-inconsistent-missing-override",
+ "-Wno-thread-safety-analysis",
+ "-Wno-thread-safety-attributes",
+ ]
+ }
+
+ aosp_deps = [
+ "shared_library:libbinder",
+ "shared_library:libcutils",
+ "shared_library:libhidlbase",
+ "shared_library:libhidltransport",
+ "shared_library:liblog",
+ "shared_library:libutils",
+ ]
+
+ subsystem_name = "multimedia"
+ part_name = "multimedia_image"
+}
diff --git a/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BnHwJpegDecode.h b/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BnHwJpegDecode.h
new file mode 100755
index 0000000000000000000000000000000000000000..9aba40c7925fe40a2add4278cb169bc547ef26fc
--- /dev/null
+++ b/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BnHwJpegDecode.h
@@ -0,0 +1,98 @@
+#ifndef HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BNHWJPEGDECODE_H
+#define HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BNHWJPEGDECODE_H
+
+#include
+
+namespace vendor {
+namespace huawei {
+namespace hardware {
+namespace jpegdec {
+namespace V1_0 {
+
+struct BnHwJpegDecode : public ::android::hidl::base::V1_0::BnHwBase {
+ explicit BnHwJpegDecode(const ::android::sp &_hidl_impl);
+ explicit BnHwJpegDecode(const ::android::sp &_hidl_impl, const std::string& HidlInstrumentor_package, const std::string& HidlInstrumentor_interface);
+
+ virtual ~BnHwJpegDecode();
+
+ ::android::status_t onTransact(
+ uint32_t _hidl_code,
+ const ::android::hardware::Parcel &_hidl_data,
+ ::android::hardware::Parcel *_hidl_reply,
+ uint32_t _hidl_flags = 0,
+ TransactCallback _hidl_cb = nullptr) override;
+
+
+ /**
+ * The pure class is what this class wraps.
+ */
+ typedef IJpegDecode Pure;
+
+ /**
+ * Type tag for use in template logic that indicates this is a 'native' class.
+ */
+ typedef android::hardware::details::bnhw_tag _hidl_tag;
+
+ ::android::sp getImpl() { return _hidl_mImpl; }
+ // Methods from ::vendor::huawei::hardware::jpegdec::V1_0::IJpegDecode follow.
+ static ::android::status_t _hidl_DoDecode(
+ ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
+ const ::android::hardware::Parcel &_hidl_data,
+ ::android::hardware::Parcel *_hidl_reply,
+ TransactCallback _hidl_cb);
+
+
+ static ::android::status_t _hidl_Alloc_OutBuffer(
+ ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
+ const ::android::hardware::Parcel &_hidl_data,
+ ::android::hardware::Parcel *_hidl_reply,
+ TransactCallback _hidl_cb);
+
+
+ static ::android::status_t _hidl_Alloc_InBuffer(
+ ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
+ const ::android::hardware::Parcel &_hidl_data,
+ ::android::hardware::Parcel *_hidl_reply,
+ TransactCallback _hidl_cb);
+
+
+ static ::android::status_t _hidl_LockDevice(
+ ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
+ const ::android::hardware::Parcel &_hidl_data,
+ ::android::hardware::Parcel *_hidl_reply,
+ TransactCallback _hidl_cb);
+
+
+ static ::android::status_t _hidl_UnLockDevice(
+ ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
+ const ::android::hardware::Parcel &_hidl_data,
+ ::android::hardware::Parcel *_hidl_reply,
+ TransactCallback _hidl_cb);
+
+
+ static ::android::status_t _hidl_GetDecodeStatus(
+ ::android::hidl::base::V1_0::BnHwBase* _hidl_this,
+ const ::android::hardware::Parcel &_hidl_data,
+ ::android::hardware::Parcel *_hidl_reply,
+ TransactCallback _hidl_cb);
+
+
+
+private:
+ // Methods from ::vendor::huawei::hardware::jpegdec::V1_0::IJpegDecode follow.
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+ ::android::hardware::Return ping();
+ using getDebugInfo_cb = ::android::hidl::base::V1_0::IBase::getDebugInfo_cb;
+ ::android::hardware::Return getDebugInfo(getDebugInfo_cb _hidl_cb);
+
+ ::android::sp _hidl_mImpl;
+};
+
+} // namespace V1_0
+} // namespace jpegdec
+} // namespace hardware
+} // namespace huawei
+} // namespace vendor
+
+#endif // HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BNHWJPEGDECODE_H
diff --git a/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BpHwJpegDecode.h b/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BpHwJpegDecode.h
new file mode 100755
index 0000000000000000000000000000000000000000..1b103478d5d58e9430b635dbc8f9afec6c9b6a52
--- /dev/null
+++ b/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BpHwJpegDecode.h
@@ -0,0 +1,68 @@
+#ifndef HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BPHWJPEGDECODE_H
+#define HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BPHWJPEGDECODE_H
+
+#include
+
+#include
+
+namespace vendor {
+namespace huawei {
+namespace hardware {
+namespace jpegdec {
+namespace V1_0 {
+
+struct BpHwJpegDecode : public ::android::hardware::BpInterface, public ::android::hardware::details::HidlInstrumentor {
+ explicit BpHwJpegDecode(const ::android::sp<::android::hardware::IBinder> &_hidl_impl);
+
+ /**
+ * The pure class is what this class wraps.
+ */
+ typedef IJpegDecode Pure;
+
+ /**
+ * Type tag for use in template logic that indicates this is a 'proxy' class.
+ */
+ typedef android::hardware::details::bphw_tag _hidl_tag;
+
+ virtual bool isRemote() const override { return true; }
+
+ // Methods from ::vendor::huawei::hardware::jpegdec::V1_0::IJpegDecode follow.
+ static ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> _hidl_DoDecode(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, const ::vendor::huawei::hardware::jpegdec::V1_0::jpeg_decompress_hidl_t& cinfo, const ::android::hardware::hidl_handle& out_info, const ::android::hardware::hidl_handle& in_info, const ::vendor::huawei::hardware::jpegdec::V1_0::hwdecode_region_info& region_info, int32_t samplesize, int32_t compressPos);
+ static ::android::hardware::Return _hidl_Alloc_OutBuffer(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, int32_t outwidth, int32_t outheight, int32_t color_format, Alloc_OutBuffer_cb _hidl_cb);
+ static ::android::hardware::Return _hidl_Alloc_InBuffer(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, int32_t size, Alloc_InBuffer_cb _hidl_cb);
+ static ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> _hidl_LockDevice(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor);
+ static ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> _hidl_UnLockDevice(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor);
+ static ::android::hardware::Return _hidl_GetDecodeStatus(::android::hardware::IInterface* _hidl_this, ::android::hardware::details::HidlInstrumentor *_hidl_this_instrumentor, GetDecodeStatus_cb _hidl_cb);
+
+ // Methods from ::vendor::huawei::hardware::jpegdec::V1_0::IJpegDecode follow.
+ ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> DoDecode(const ::vendor::huawei::hardware::jpegdec::V1_0::jpeg_decompress_hidl_t& cinfo, const ::android::hardware::hidl_handle& out_info, const ::android::hardware::hidl_handle& in_info, const ::vendor::huawei::hardware::jpegdec::V1_0::hwdecode_region_info& region_info, int32_t samplesize, int32_t compressPos) override;
+ ::android::hardware::Return Alloc_OutBuffer(int32_t outwidth, int32_t outheight, int32_t color_format, Alloc_OutBuffer_cb _hidl_cb) override;
+ ::android::hardware::Return Alloc_InBuffer(int32_t size, Alloc_InBuffer_cb _hidl_cb) override;
+ ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> LockDevice() override;
+ ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> UnLockDevice() override;
+ ::android::hardware::Return GetDecodeStatus(GetDecodeStatus_cb _hidl_cb) override;
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+ ::android::hardware::Return interfaceChain(interfaceChain_cb _hidl_cb) override;
+ ::android::hardware::Return debug(const ::android::hardware::hidl_handle& fd, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& options) override;
+ ::android::hardware::Return interfaceDescriptor(interfaceDescriptor_cb _hidl_cb) override;
+ ::android::hardware::Return getHashChain(getHashChain_cb _hidl_cb) override;
+ ::android::hardware::Return setHALInstrumentation() override;
+ ::android::hardware::Return linkToDeath(const ::android::sp<::android::hardware::hidl_death_recipient>& recipient, uint64_t cookie) override;
+ ::android::hardware::Return ping() override;
+ ::android::hardware::Return getDebugInfo(getDebugInfo_cb _hidl_cb) override;
+ ::android::hardware::Return notifySyspropsChanged() override;
+ ::android::hardware::Return unlinkToDeath(const ::android::sp<::android::hardware::hidl_death_recipient>& recipient) override;
+
+private:
+ std::mutex _hidl_mMutex;
+ std::vector<::android::sp<::android::hardware::hidl_binder_death_recipient>> _hidl_mDeathRecipients;
+};
+
+} // namespace V1_0
+} // namespace jpegdec
+} // namespace hardware
+} // namespace huawei
+} // namespace vendor
+
+#endif // HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BPHWJPEGDECODE_H
diff --git a/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BsJpegDecode.h b/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BsJpegDecode.h
new file mode 100755
index 0000000000000000000000000000000000000000..12e8dd0500ead02a93a9172b7debee96160496f9
--- /dev/null
+++ b/adapter/hals/jpegdec/include/vendor/huawei/hardware/jpegdec/1.0/BsJpegDecode.h
@@ -0,0 +1,556 @@
+#ifndef HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BSJPEGDECODE_H
+#define HIDL_GENERATED_VENDOR_HUAWEI_HARDWARE_JPEGDEC_V1_0_BSJPEGDECODE_H
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+namespace vendor {
+namespace huawei {
+namespace hardware {
+namespace jpegdec {
+namespace V1_0 {
+
+struct BsJpegDecode : IJpegDecode, ::android::hardware::details::HidlInstrumentor {
+ explicit BsJpegDecode(const ::android::sp impl);
+
+ /**
+ * The pure class is what this class wraps.
+ */
+ typedef IJpegDecode Pure;
+
+ typedef android::hardware::details::bs_tag _hidl_tag;
+
+ // Methods from ::vendor::huawei::hardware::jpegdec::V1_0::IJpegDecode follow.
+ ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> DoDecode(const ::vendor::huawei::hardware::jpegdec::V1_0::jpeg_decompress_hidl_t& cinfo, const ::android::hardware::hidl_handle& out_info, const ::android::hardware::hidl_handle& in_info, const ::vendor::huawei::hardware::jpegdec::V1_0::hwdecode_region_info& region_info, int32_t samplesize, int32_t compressPos) override {
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::DoDecode::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&cinfo);
+ _hidl_args.push_back((void *)&out_info);
+ _hidl_args.push_back((void *)&in_info);
+ _hidl_args.push_back((void *)®ion_info);
+ _hidl_args.push_back((void *)&samplesize);
+ _hidl_args.push_back((void *)&compressPos);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "DoDecode", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->DoDecode(cinfo, out_info, in_info, region_info, samplesize, compressPos);
+
+ ::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error _hidl_out_error = _hidl_return;
+ (void) _hidl_out_error;
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&_hidl_out_error);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "DoDecode", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+ ::android::hardware::Return Alloc_OutBuffer(int32_t outwidth, int32_t outheight, int32_t color_format, Alloc_OutBuffer_cb _hidl_cb) override {
+ if (_hidl_cb == nullptr) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_ILLEGAL_ARGUMENT,
+ "Null synchronous callback passed.");
+ }
+
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::Alloc_OutBuffer::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&outwidth);
+ _hidl_args.push_back((void *)&outheight);
+ _hidl_args.push_back((void *)&color_format);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "Alloc_OutBuffer", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->Alloc_OutBuffer(outwidth, outheight, color_format, [&](const auto &_hidl_out_error, const auto &_hidl_out_outinfo) {
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&_hidl_out_error);
+ _hidl_args.push_back((void *)&_hidl_out_outinfo);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "Alloc_OutBuffer", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ _hidl_cb(_hidl_out_error, _hidl_out_outinfo);
+ });
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+ ::android::hardware::Return Alloc_InBuffer(int32_t size, Alloc_InBuffer_cb _hidl_cb) override {
+ if (_hidl_cb == nullptr) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_ILLEGAL_ARGUMENT,
+ "Null synchronous callback passed.");
+ }
+
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::Alloc_InBuffer::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&size);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "Alloc_InBuffer", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->Alloc_InBuffer(size, [&](const auto &_hidl_out_error, const auto &_hidl_out_outinfo) {
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&_hidl_out_error);
+ _hidl_args.push_back((void *)&_hidl_out_outinfo);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "Alloc_InBuffer", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ _hidl_cb(_hidl_out_error, _hidl_out_outinfo);
+ });
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+ ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> LockDevice() override {
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::LockDevice::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "LockDevice", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->LockDevice();
+
+ ::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error _hidl_out_error = _hidl_return;
+ (void) _hidl_out_error;
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&_hidl_out_error);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "LockDevice", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+ ::android::hardware::Return<::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error> UnLockDevice() override {
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::UnLockDevice::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "UnLockDevice", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->UnLockDevice();
+
+ ::vendor::huawei::hardware::jpegdec::V1_0::JPEG_Error _hidl_out_error = _hidl_return;
+ (void) _hidl_out_error;
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&_hidl_out_error);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "UnLockDevice", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+ ::android::hardware::Return GetDecodeStatus(GetDecodeStatus_cb _hidl_cb) override {
+ if (_hidl_cb == nullptr) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_ILLEGAL_ARGUMENT,
+ "Null synchronous callback passed.");
+ }
+
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::GetDecodeStatus::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "GetDecodeStatus", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->GetDecodeStatus([&](const auto &_hidl_out_error, const auto &_hidl_out_status) {
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&_hidl_out_error);
+ _hidl_args.push_back((void *)&_hidl_out_status);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "vendor.huawei.hardware.jpegdec", "1.0", "IJpegDecode", "GetDecodeStatus", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ _hidl_cb(_hidl_out_error, _hidl_out_status);
+ });
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+
+ // Methods from ::android::hidl::base::V1_0::IBase follow.
+ ::android::hardware::Return interfaceChain(interfaceChain_cb _hidl_cb) override {
+ if (_hidl_cb == nullptr) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_ILLEGAL_ARGUMENT,
+ "Null synchronous callback passed.");
+ }
+
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::interfaceChain::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "android.hidl.base", "1.0", "IBase", "interfaceChain", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->interfaceChain([&](const auto &_hidl_out_descriptors) {
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&_hidl_out_descriptors);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "android.hidl.base", "1.0", "IBase", "interfaceChain", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ _hidl_cb(_hidl_out_descriptors);
+ });
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+ ::android::hardware::Return debug(const ::android::hardware::hidl_handle& fd, const ::android::hardware::hidl_vec<::android::hardware::hidl_string>& options) override {
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::debug::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ _hidl_args.push_back((void *)&fd);
+ _hidl_args.push_back((void *)&options);
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_ENTRY, "android.hidl.base", "1.0", "IBase", "debug", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ ::android::hardware::Status _hidl_error = ::android::hardware::Status::ok();
+ auto _hidl_return = mImpl->debug(fd, options);
+
+ atrace_end(ATRACE_TAG_HAL);
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector _hidl_args;
+ for (const auto &callback: mInstrumentationCallbacks) {
+ callback(InstrumentationEvent::PASSTHROUGH_EXIT, "android.hidl.base", "1.0", "IBase", "debug", &_hidl_args);
+ }
+ }
+ #endif // __ANDROID_DEBUGGABLE__
+
+ if (!_hidl_error.isOk()) return _hidl_error;
+ return _hidl_return;
+ }
+ ::android::hardware::Return interfaceDescriptor(interfaceDescriptor_cb _hidl_cb) override {
+ if (_hidl_cb == nullptr) {
+ return ::android::hardware::Status::fromExceptionCode(
+ ::android::hardware::Status::EX_ILLEGAL_ARGUMENT,
+ "Null synchronous callback passed.");
+ }
+
+ atrace_begin(ATRACE_TAG_HAL, "HIDL::IJpegDecode::interfaceDescriptor::passthrough");
+ #ifdef __ANDROID_DEBUGGABLE__
+ if (UNLIKELY(mEnableInstrumentation)) {
+ std::vector