1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "image_processing.h"
17 
18 #include <atomic>
19 #include <functional>
20 
21 #include "vpe_log.h"
22 
23 #include "image_processing_capability.h"
24 #include "image_processing_impl.h"
25 #include "image_processing_loader.h"
26 
27 using namespace OHOS::Media::VideoProcessingEngine;
28 
29 const int32_t IMAGE_PROCESSING_TYPE_COLOR_SPACE_CONVERSION = 0x1;
30 const int32_t IMAGE_PROCESSING_TYPE_COMPOSITION = 0x2;
31 const int32_t IMAGE_PROCESSING_TYPE_DECOMPOSITION = 0x4;
32 const int32_t IMAGE_PROCESSING_TYPE_METADATA_GENERATION = 0x8;
33 const int32_t IMAGE_PROCESSING_TYPE_DETAIL_ENHANCER = 0x10;
34 const char* IMAGE_DETAIL_ENHANCER_PARAMETER_KEY_QUALITY_LEVEL = "QualityLevel";
35 
36 namespace {
37 std::atomic<bool> g_isInit = false;
38 
CallImageProcessingSupport(std::function<bool (void)> && operation,std::function<bool (ImageProcessingNdkLoader &)> && operationLoader)39 bool CallImageProcessingSupport(
40     std::function<bool(void)>&& operation,
41     std::function<bool(ImageProcessingNdkLoader&)>&& operationLoader)
42 {
43     if (ImageProcessingNdkLoader::Get().LoadLibrary()) {
44         auto support = operationLoader(ImageProcessingNdkLoader::Get());
45         ImageProcessingNdkLoader::Get().UnloadLibrary();
46         return support;
47     }
48     return operation();
49 }
50 
CallImageProcessing(OH_ImageProcessing * instance,std::function<ImageProcessing_ErrorCode (std::shared_ptr<ImageProcessingNative> &)> && operation,std::function<ImageProcessing_ErrorCode (ImageProcessingNdkLoader &)> && operationLoader)51 ImageProcessing_ErrorCode CallImageProcessing(
52     OH_ImageProcessing* instance,
53     std::function<ImageProcessing_ErrorCode(std::shared_ptr<ImageProcessingNative>&)>&& operation,
54     std::function<ImageProcessing_ErrorCode(ImageProcessingNdkLoader&)>&& operationLoader)
55 {
56     if (ImageProcessingNdkLoader::Get().IsValid()) {
57         return operationLoader(ImageProcessingNdkLoader::Get());
58     }
59     if (instance == nullptr) {
60         VPE_LOGE("instance is null!");
61         return IMAGE_PROCESSING_ERROR_INVALID_PARAMETER;
62     }
63     auto obj = instance->GetObj();
64     if (obj == nullptr) {
65         VPE_LOGE("instance is invalid!");
66         return IMAGE_PROCESSING_ERROR_INVALID_INSTANCE;
67     }
68     return operation(obj);
69 }
70 
CallImageProcessingWithLoad(std::function<ImageProcessing_ErrorCode (void)> && operation,std::function<ImageProcessing_ErrorCode (ImageProcessingNdkLoader &)> && operationLoader)71 ImageProcessing_ErrorCode CallImageProcessingWithLoad(
72     std::function<ImageProcessing_ErrorCode(void)>&& operation,
73     std::function<ImageProcessing_ErrorCode(ImageProcessingNdkLoader&)>&& operationLoader)
74 {
75     if (ImageProcessingNdkLoader::Get().LoadLibrary()) {
76         return operationLoader(ImageProcessingNdkLoader::Get());
77     }
78     return operation();
79 }
80 
CallImageProcessingWithUnload(std::function<ImageProcessing_ErrorCode (void)> && operation,std::function<ImageProcessing_ErrorCode (ImageProcessingNdkLoader &)> && operationLoader)81 ImageProcessing_ErrorCode CallImageProcessingWithUnload(
82     std::function<ImageProcessing_ErrorCode(void)>&& operation,
83     std::function<ImageProcessing_ErrorCode(ImageProcessingNdkLoader&)>&& operationLoader)
84 {
85     if (ImageProcessingNdkLoader::Get().IsValid()) {
86         auto ret = operationLoader(ImageProcessingNdkLoader::Get());
87         if (ret == IMAGE_PROCESSING_SUCCESS) {
88             ImageProcessingNdkLoader::Get().UnloadLibrary();
89         }
90         return ret;
91     }
92     return operation();
93 }
94 }
95 
OH_ImageProcessing_InitializeEnvironment(void)96 ImageProcessing_ErrorCode OH_ImageProcessing_InitializeEnvironment(void)
97 {
98     return CallImageProcessingWithLoad(
99         []() {
100             g_isInit = true;
101             return IMAGE_PROCESSING_SUCCESS;
102         },
103         [](ImageProcessingNdkLoader& loader) { return loader.InitializeEnvironment(); });
104 }
105 
OH_ImageProcessing_DeinitializeEnvironment(void)106 ImageProcessing_ErrorCode OH_ImageProcessing_DeinitializeEnvironment(void)
107 {
108     return CallImageProcessingWithUnload(
109         []() {
110             if (!g_isInit.load()) {
111                 return IMAGE_PROCESSING_ERROR_OPERATION_NOT_PERMITTED;
112             }
113             g_isInit = false;
114             return IMAGE_PROCESSING_SUCCESS;
115         },
116         [](ImageProcessingNdkLoader& loader) { return loader.DeinitializeEnvironment(); });
117 }
118 
OH_ImageProcessing_IsColorSpaceConversionSupported(const ImageProcessing_ColorSpaceInfo * sourceImageInfo,const ImageProcessing_ColorSpaceInfo * destinationImageInfo)119 bool OH_ImageProcessing_IsColorSpaceConversionSupported(
120     const ImageProcessing_ColorSpaceInfo* sourceImageInfo,
121     const ImageProcessing_ColorSpaceInfo* destinationImageInfo)
122 {
123     return CallImageProcessingSupport([sourceImageInfo, destinationImageInfo]() {
124             return ImageProcessingCapability::IsColorSpaceConversionSupported(sourceImageInfo, destinationImageInfo);
125         }, [sourceImageInfo, destinationImageInfo](ImageProcessingNdkLoader& loader) {
126             return loader.IsColorSpaceConversionSupported(sourceImageInfo, destinationImageInfo);
127         });
128     }
129 
OH_ImageProcessing_IsCompositionSupported(const ImageProcessing_ColorSpaceInfo * sourceImageInfo,const ImageProcessing_ColorSpaceInfo * sourceGainmapInfo,const ImageProcessing_ColorSpaceInfo * destinationImageInfo)130 bool OH_ImageProcessing_IsCompositionSupported(
131     const ImageProcessing_ColorSpaceInfo* sourceImageInfo,
132     const ImageProcessing_ColorSpaceInfo* sourceGainmapInfo,
133     const ImageProcessing_ColorSpaceInfo* destinationImageInfo)
134 {
135     return CallImageProcessingSupport([sourceImageInfo, sourceGainmapInfo, destinationImageInfo]() {
136             return ImageProcessingCapability::IsCompositionSupported(sourceImageInfo,
137                 sourceGainmapInfo, destinationImageInfo);
138         }, [sourceImageInfo, sourceGainmapInfo, destinationImageInfo](ImageProcessingNdkLoader& loader) {
139             return loader.IsCompositionSupported(sourceImageInfo, sourceGainmapInfo, destinationImageInfo);
140         });
141 }
142 
OH_ImageProcessing_IsDecompositionSupported(const ImageProcessing_ColorSpaceInfo * sourceImageInfo,const ImageProcessing_ColorSpaceInfo * destinationImageInfo,const ImageProcessing_ColorSpaceInfo * destinationGainmapInfo)143 bool OH_ImageProcessing_IsDecompositionSupported(
144     const ImageProcessing_ColorSpaceInfo* sourceImageInfo,
145     const ImageProcessing_ColorSpaceInfo* destinationImageInfo,
146     const ImageProcessing_ColorSpaceInfo* destinationGainmapInfo)
147 {
148     return CallImageProcessingSupport(
149         [sourceImageInfo, destinationImageInfo, destinationGainmapInfo]() {
150             return ImageProcessingCapability::IsDecompositionSupported(sourceImageInfo, destinationImageInfo,
151                 destinationGainmapInfo);
152         }, [sourceImageInfo, destinationImageInfo, destinationGainmapInfo](ImageProcessingNdkLoader& loader) {
153             return loader.IsDecompositionSupported(sourceImageInfo, destinationImageInfo, destinationGainmapInfo);
154         });
155 }
156 
OH_ImageProcessing_IsMetadataGenerationSupported(const ImageProcessing_ColorSpaceInfo * sourceImageInfo)157 bool OH_ImageProcessing_IsMetadataGenerationSupported(const ImageProcessing_ColorSpaceInfo* sourceImageInfo)
158 {
159     return CallImageProcessingSupport([sourceImageInfo]() {
160             return ImageProcessingCapability::IsMetadataGenerationSupported(sourceImageInfo);
161         }, [sourceImageInfo](ImageProcessingNdkLoader& loader) {
162             return loader.IsMetadataGenerationSupported(sourceImageInfo);
163         });
164 }
165 
OH_ImageProcessing_Create(OH_ImageProcessing ** imageProcessor,int type)166 ImageProcessing_ErrorCode OH_ImageProcessing_Create(OH_ImageProcessing** imageProcessor, int type)
167 {
168     return CallImageProcessingWithLoad([imageProcessor, type]() {
169             return OH_ImageProcessing::Create(imageProcessor, type);
170         }, [imageProcessor, type](ImageProcessingNdkLoader& loader) {
171             return loader.Create(imageProcessor, type);
172         });
173 }
174 
OH_ImageProcessing_Destroy(OH_ImageProcessing * imageProcessor)175 ImageProcessing_ErrorCode OH_ImageProcessing_Destroy(OH_ImageProcessing* imageProcessor)
176 {
177     return CallImageProcessingWithUnload([imageProcessor]() { return OH_ImageProcessing::Destroy(imageProcessor); },
178         [imageProcessor](ImageProcessingNdkLoader& loader) { return loader.Destroy(imageProcessor); });
179 }
180 
OH_ImageProcessing_SetParameter(OH_ImageProcessing * imageProcessor,const OH_AVFormat * parameter)181 ImageProcessing_ErrorCode OH_ImageProcessing_SetParameter(OH_ImageProcessing* imageProcessor,
182     const OH_AVFormat* parameter)
183 {
184     return CallImageProcessing(imageProcessor, [parameter](std::shared_ptr<ImageProcessingNative>& obj) {
185         return obj->SetParameter(parameter);
186     }, [imageProcessor, parameter](ImageProcessingNdkLoader& loader) {
187         return loader.SetParameter(imageProcessor, parameter);
188     });
189 }
190 
OH_ImageProcessing_GetParameter(OH_ImageProcessing * imageProcessor,OH_AVFormat * parameter)191 ImageProcessing_ErrorCode OH_ImageProcessing_GetParameter(OH_ImageProcessing* imageProcessor, OH_AVFormat* parameter)
192 {
193     return CallImageProcessing(imageProcessor, [parameter](std::shared_ptr<ImageProcessingNative>& obj) {
194         return obj->GetParameter(parameter);
195     }, [imageProcessor, parameter](ImageProcessingNdkLoader& loader) {
196         return loader.GetParameter(imageProcessor, parameter);
197     });
198 }
199 
OH_ImageProcessing_ConvertColorSpace(OH_ImageProcessing * imageProcessor,OH_PixelmapNative * sourceImage,OH_PixelmapNative * destinationImage)200 ImageProcessing_ErrorCode OH_ImageProcessing_ConvertColorSpace(OH_ImageProcessing* imageProcessor,
201     OH_PixelmapNative* sourceImage, OH_PixelmapNative* destinationImage)
202 {
203     return CallImageProcessing(imageProcessor,
204         [sourceImage, destinationImage](std::shared_ptr<ImageProcessingNative>& obj) {
205             return obj->ConvertColorSpace(sourceImage, destinationImage);
206         }, [imageProcessor, sourceImage, destinationImage](ImageProcessingNdkLoader& loader) {
207         return loader.ConvertColorSpace(imageProcessor, sourceImage, destinationImage);
208         });
209 }
210 
OH_ImageProcessing_Compose(OH_ImageProcessing * imageProcessor,OH_PixelmapNative * sourceImage,OH_PixelmapNative * sourceGainmap,OH_PixelmapNative * destinationImage)211 ImageProcessing_ErrorCode OH_ImageProcessing_Compose(OH_ImageProcessing* imageProcessor,
212     OH_PixelmapNative* sourceImage, OH_PixelmapNative* sourceGainmap, OH_PixelmapNative* destinationImage)
213 {
214     return CallImageProcessing(imageProcessor,
215         [sourceImage, sourceGainmap, destinationImage](std::shared_ptr<ImageProcessingNative>& obj) {
216             return obj->Compose(sourceImage, sourceGainmap, destinationImage);
217         }, [imageProcessor, sourceImage, sourceGainmap, destinationImage](ImageProcessingNdkLoader& loader) {
218             return loader.Compose(imageProcessor, sourceImage, sourceGainmap, destinationImage);
219         });
220 }
221 
OH_ImageProcessing_Decompose(OH_ImageProcessing * imageProcessor,OH_PixelmapNative * sourceImage,OH_PixelmapNative * destinationImage,OH_PixelmapNative * destinationGainmap)222 ImageProcessing_ErrorCode OH_ImageProcessing_Decompose(OH_ImageProcessing* imageProcessor,
223     OH_PixelmapNative* sourceImage, OH_PixelmapNative* destinationImage, OH_PixelmapNative* destinationGainmap)
224 {
225     return CallImageProcessing(imageProcessor,
226         [sourceImage, destinationImage, destinationGainmap](std::shared_ptr<ImageProcessingNative>& obj) {
227             return obj->Decompose(sourceImage, destinationImage, destinationGainmap);
228         }, [imageProcessor, sourceImage, destinationImage, destinationGainmap](ImageProcessingNdkLoader& loader) {
229             return loader.Decompose(imageProcessor, sourceImage, destinationImage, destinationGainmap);
230         });
231 }
232 
OH_ImageProcessing_GenerateMetadata(OH_ImageProcessing * imageProcessor,OH_PixelmapNative * sourceImage)233 ImageProcessing_ErrorCode OH_ImageProcessing_GenerateMetadata(OH_ImageProcessing* imageProcessor,
234     OH_PixelmapNative* sourceImage)
235 {
236     return CallImageProcessing(imageProcessor, [sourceImage](std::shared_ptr<ImageProcessingNative>& obj) {
237         return obj->GenerateMetadata(sourceImage);
238     }, [imageProcessor, sourceImage](ImageProcessingNdkLoader& loader) {
239         return loader.GenerateMetadata(imageProcessor, sourceImage);
240     });
241 }
242 
OH_ImageProcessing_EnhanceDetail(OH_ImageProcessing * imageProcessor,OH_PixelmapNative * sourceImage,OH_PixelmapNative * destinationImage)243 ImageProcessing_ErrorCode OH_ImageProcessing_EnhanceDetail(OH_ImageProcessing* imageProcessor,
244     OH_PixelmapNative* sourceImage, OH_PixelmapNative* destinationImage)
245 {
246     return CallImageProcessing(imageProcessor,
247         [sourceImage, destinationImage](std::shared_ptr<ImageProcessingNative>& obj) {
248             return obj->EnhanceDetail(sourceImage, destinationImage);
249         }, [imageProcessor, sourceImage, destinationImage](ImageProcessingNdkLoader& loader) {
250             return loader.EnhanceDetail(imageProcessor, sourceImage, destinationImage);
251         });
252 }
253