• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2025 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_ani_utils.h"
17 #include <array>
18 #include <iostream>
19 #include "pixel_map_ani.h"
20 #include "log_tags.h"
21 #include "media_errors.h"
22 #include "image_log.h"
23 
24 #undef LOG_DOMAIN
25 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
26 
27 #undef LOG_TAG
28 #define LOG_TAG "AniUtilsAni"
29 
30 namespace OHOS {
31 namespace Media {
32 using namespace std;
33 
GetPixelMapFromEnv(ani_env * env,ani_object obj)34 PixelMap* ImageAniUtils::GetPixelMapFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj)
35 {
36     return ImageAniUtils::GetPixelMapFromEnvSp(env, obj).get();
37 }
38 
GetPixelMapFromEnvSp(ani_env * env,ani_object obj)39 shared_ptr<PixelMap> ImageAniUtils::GetPixelMapFromEnvSp([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj)
40 {
41     ani_status ret;
42     ani_long nativeObj {};
43     if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) {
44         IMAGE_LOGE("[GetPixelMapFromEnv] Object_GetField_Long fetch failed");
45         return nullptr;
46     }
47     PixelMapAni* pixelmapAni = reinterpret_cast<PixelMapAni*>(nativeObj);
48     if (!pixelmapAni) {
49         IMAGE_LOGE("[GetPixelMapFromEnv] pixelmapAni nullptr");
50         return nullptr;
51     }
52     return pixelmapAni->nativePixelMap_;
53 }
54 
GetImageSourceAniFromEnv(ani_env * env,ani_object obj)55 ImageSourceAni* ImageAniUtils::GetImageSourceAniFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj)
56 {
57     ani_status ret;
58     ani_long nativeObj {};
59     if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) {
60         IMAGE_LOGE("[GetImageSourceFromEnv] Object_GetField_Long fetch failed");
61         return nullptr;
62     }
63     return reinterpret_cast<ImageSourceAni*>(nativeObj);
64 }
65 
GetImageSourceFromEnv(ani_env * env,ani_object obj)66 shared_ptr<ImageSource> ImageAniUtils::GetImageSourceFromEnv([[maybe_unused]] ani_env* env,
67     [[maybe_unused]] ani_object obj)
68 {
69     ImageSourceAni* imageSourceAni = ImageAniUtils::GetImageSourceAniFromEnv(env, obj);
70     if (!imageSourceAni) {
71         IMAGE_LOGE("[GetPictureFromEnv] imageSourceAni nullptr");
72         return nullptr;
73     }
74     return imageSourceAni->nativeImageSource_;
75 }
76 
GetPictureFromEnv(ani_env * env,ani_object obj)77 shared_ptr<Picture> ImageAniUtils::GetPictureFromEnv([[maybe_unused]] ani_env* env, [[maybe_unused]] ani_object obj)
78 {
79     ani_status ret;
80     ani_long nativeObj {};
81     if ((ret = env->Object_GetFieldByName_Long(obj, "nativeObj", &nativeObj)) != ANI_OK) {
82         IMAGE_LOGE("[GetPictureFromEnv] Object_GetField_Long fetch failed");
83         return nullptr;
84     }
85     PictureAni* pictureAni = reinterpret_cast<PictureAni*>(nativeObj);
86     if (!pictureAni) {
87         IMAGE_LOGE("[GetPictureFromEnv] pictureAni nullptr");
88         return nullptr;
89     }
90     return pictureAni->nativePicture_;
91 }
92 
CreateAniImageInfo(ani_env * env)93 static ani_object CreateAniImageInfo(ani_env* env)
94 {
95     static const char* imageInfoClassName = "L@ohos/multimedia/image/image/ImageInfoInner;";
96     ani_class imageInfoCls;
97     if (ANI_OK != env->FindClass(imageInfoClassName, &imageInfoCls)) {
98         IMAGE_LOGE("Not found L@ohos/multimedia/image/image/ImageInfoInner;");
99         return nullptr;
100     }
101     ani_method imageInfoCtor;
102     if (ANI_OK != env->Class_FindMethod(imageInfoCls, "<ctor>", nullptr, &imageInfoCtor)) {
103         IMAGE_LOGE("Not found Class_FindMethod");
104         return nullptr;
105     }
106     ani_object imageInfoValue;
107     if (ANI_OK != env->Object_New(imageInfoCls, imageInfoCtor, &imageInfoValue)) {
108         IMAGE_LOGE("New Context Fail");
109         return nullptr;
110     }
111     return imageInfoValue;
112 }
113 
SetImageInfoSize(ani_env * env,const ImageInfo & imgInfo,ani_object & imageInfoValue)114 static bool SetImageInfoSize(ani_env* env, const ImageInfo& imgInfo, ani_object& imageInfoValue)
115 {
116     ani_ref sizeref;
117     if (ANI_OK != env->Object_CallMethodByName_Ref(imageInfoValue, "<get>size",
118         ":L@ohos/multimedia/image/image/Size;", &sizeref)) {
119         IMAGE_LOGE("Object_CallMethodByName_Ref failed");
120         return false;
121     }
122     ani_object sizeObj = reinterpret_cast<ani_object>(sizeref);
123     if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "<set>width", "I:V",
124         static_cast<ani_int>(imgInfo.size.width))) {
125         IMAGE_LOGE("Object_CallMethodByName_Void <set>width failed");
126         return false;
127     }
128     if (ANI_OK != env->Object_CallMethodByName_Void(sizeObj, "<set>height", "I:V",
129         static_cast<ani_int>(imgInfo.size.height))) {
130         IMAGE_LOGE("Object_CallMethodByName_Void <set>height failed");
131         return false;
132     }
133     return true;
134 }
135 
getPixelFormatItemName(PixelFormat format)136 static string getPixelFormatItemName(PixelFormat format)
137 {
138     switch (format) {
139         case PixelFormat::ARGB_8888:
140             return "ARGB_8888";
141         case PixelFormat::RGB_565:
142             return "RGB_565";
143         case PixelFormat::RGBA_8888:
144             return "RGBA_8888";
145         case PixelFormat::BGRA_8888:
146             return "BGRA_8888";
147         case PixelFormat::RGB_888:
148             return "RGB_888";
149         case PixelFormat::ALPHA_8:
150             return "ALPHA_8";
151         case PixelFormat::RGBA_F16:
152             return "RGBA_F16";
153         case PixelFormat::NV21:
154             return "NV21";
155         case PixelFormat::NV12:
156             return "NV12";
157         case PixelFormat::RGBA_1010102:
158             return "RGBA_1010102";
159         case PixelFormat::YCBCR_P010:
160             return "YCBCR_P010";
161         case PixelFormat::YCRCB_P010:
162             return "YCRCB_P010";
163         case PixelFormat::ASTC_4x4:
164             return "ASTC_4x4";
165         default:
166             return "UNKNOWN";
167     }
168 }
169 
findPixelFormatEnumItem(ani_env * env,PixelFormat format)170 static ani_enum_item findPixelFormatEnumItem([[maybe_unused]] ani_env* env, PixelFormat format)
171 {
172     ani_enum type;
173     if (ANI_OK != env->FindEnum("L@ohos/multimedia/image/image/PixelMapFormat;", &type)) {
174         IMAGE_LOGE("FindEnum for PixelMapFormat Failed");
175         return {};
176     }
177 
178     string itemName = getPixelFormatItemName(format);
179 
180     ani_enum_item enumItem;
181     if (ANI_OK != env->Enum_GetEnumItemByName(type, itemName.c_str(), &enumItem)) {
182         IMAGE_LOGE("Enum_GetEnumItemByName for PixelMapFormat Failed");
183         return {};
184     }
185 
186     return enumItem;
187 }
188 
getAlphaTypeItemName(AlphaType alphaType)189 static string getAlphaTypeItemName(AlphaType alphaType)
190 {
191     switch (alphaType) {
192         case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
193             return "OPAQUE";
194         case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
195             return "PREMUL";
196         case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
197             return "UNPREMUL";
198         default:
199             return "UNKNOWN";
200     }
201 }
202 
findAlphaTypeEnumItem(ani_env * env,AlphaType alphaType)203 static ani_enum_item findAlphaTypeEnumItem([[maybe_unused]] ani_env* env, AlphaType alphaType)
204 {
205     ani_enum type;
206     if (ANI_OK != env->FindEnum("L@ohos/multimedia/image/image/AlphaType;", &type)) {
207         IMAGE_LOGE("FindEnum for AlphaType Failed");
208         return {};
209     }
210 
211     string itemName = getAlphaTypeItemName(alphaType);
212 
213     ani_enum_item enumItem;
214     if (ANI_OK != env->Enum_GetEnumItemByName(type, itemName.c_str(), &enumItem)) {
215         IMAGE_LOGE("Enum_GetEnumItemByName for AlphaType Failed");
216         return {};
217     }
218 
219     return enumItem;
220 }
221 
CreateImageInfoValueFromNative(ani_env * env,const ImageInfo & imgInfo,PixelMap * pixelmap)222 ani_object ImageAniUtils::CreateImageInfoValueFromNative(ani_env* env, const ImageInfo &imgInfo, PixelMap* pixelmap)
223 {
224     ani_object imageInfoValue = CreateAniImageInfo(env);
225     if (imageInfoValue == nullptr) {
226         return nullptr;
227     }
228 
229     if (!SetImageInfoSize(env, imgInfo, imageInfoValue)) {
230         return nullptr;
231     }
232     if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "<set>density", "I:V",
233         static_cast<ani_int>(imgInfo.baseDensity))) {
234         IMAGE_LOGE("Object_CallMethodByName_Void <set>density failed");
235         return nullptr;
236     }
237     if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "<set>stride", "I:V",
238         static_cast<ani_int>(imgInfo.size.height))) {
239         IMAGE_LOGE("Object_CallMethodByName_Void <set>stride failed");
240         return nullptr;
241     }
242     if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "<set>pixelFormat",
243         "L@ohos/multimedia/image/image/PixelMapFormat;:V", findPixelFormatEnumItem(env, imgInfo.pixelFormat))) {
244         IMAGE_LOGE("Object_CallMethodByName_Void <set>pixelFormat failed");
245         return nullptr;
246     }
247     if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "<set>alphaType",
248         "L@ohos/multimedia/image/image/AlphaType;:V", findAlphaTypeEnumItem(env, imgInfo.alphaType))) {
249         IMAGE_LOGE("Object_CallMethodByName_Void <set>alphaType failed");
250         return nullptr;
251     }
252     ani_string encodeStr = ImageAniUtils::GetAniString(env, imgInfo.encodedFormat);
253     if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "<set>mimeType",
254         "Lstd/core/String;:V", encodeStr)) {
255         IMAGE_LOGE("Object_CallMethodByName_Void <set>encodedFormat failed ");
256         return nullptr;
257     }
258 
259     if (pixelmap != nullptr) {
260         if (ANI_OK != env->Object_CallMethodByName_Void(imageInfoValue, "<set>isHdr", "Z:V", pixelmap->IsHdr())) {
261             IMAGE_LOGE("Object_CallMethodByName_Void <set>isHdr failed ");
262             return nullptr;
263         }
264     }
265     return imageInfoValue;
266 }
267 
CreateAniPixelMap(ani_env * env,std::unique_ptr<PixelMapAni> & pPixelMapAni)268 ani_object ImageAniUtils::CreateAniPixelMap(ani_env* env, std::unique_ptr<PixelMapAni>& pPixelMapAni)
269 {
270     static const char* className = "L@ohos/multimedia/image/image/PixelMapInner;";
271     ani_class cls;
272     if (ANI_OK != env->FindClass(className, &cls)) {
273         IMAGE_LOGE("Not found L@ohos/multimedia/image/image/PixelMapInner;");
274         return nullptr;
275     }
276     ani_method ctor;
277     if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", "J:V", &ctor)) {
278         IMAGE_LOGE("Not found <ctor>");
279         return nullptr;
280     }
281     ani_object aniValue;
282     if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast<ani_long>(pPixelMapAni.release()))) {
283         IMAGE_LOGE("New Context Fail");
284     }
285     return aniValue;
286 }
287 
CreateAniImageSource(ani_env * env,std::unique_ptr<ImageSourceAni> & pImageSourceAni)288 ani_object ImageAniUtils::CreateAniImageSource(ani_env* env, std::unique_ptr<ImageSourceAni>& pImageSourceAni)
289 {
290     static const char* className = "L@ohos/multimedia/image/image/ImageSourceInner;";
291     ani_class cls;
292     if (ANI_OK != env->FindClass(className, &cls)) {
293         IMAGE_LOGE("Not found L@ohos/multimedia/image/image/ImageSourceInner;");
294         return nullptr;
295     }
296 
297     ani_method ctor;
298     if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", "J:V", &ctor)) {
299         IMAGE_LOGE("Not found <ctor>");
300         return nullptr;
301     }
302 
303     ani_object aniValue;
304     if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast<ani_long>(pImageSourceAni.release()))) {
305         IMAGE_LOGE("New Context Fail");
306     }
307     return aniValue;
308 }
309 
CreateAniPicture(ani_env * env,std::unique_ptr<PictureAni> & pPictureAni)310 ani_object ImageAniUtils::CreateAniPicture(ani_env* env, std::unique_ptr<PictureAni>& pPictureAni)
311 {
312     static const char* className = "L@ohos/multimedia/image/image/PictureInner;";
313     ani_class cls;
314     if (ANI_OK != env->FindClass(className, &cls)) {
315         IMAGE_LOGE("Not found L@ohos/multimedia/image/image/PictureInner;");
316         return nullptr;
317     }
318     ani_method ctor;
319     if (ANI_OK != env->Class_FindMethod(cls, "<ctor>", "J:V", &ctor)) {
320         IMAGE_LOGE("Not found <ctor>");
321         return nullptr;
322     }
323     ani_object aniValue;
324     if (ANI_OK != env->Object_New(cls, ctor, &aniValue, reinterpret_cast<ani_long>(pPictureAni.release()))) {
325         IMAGE_LOGE("New Context Fail");
326     }
327     return aniValue;
328 }
329 
GetAniString(ani_env * env,const string & str)330 ani_string ImageAniUtils::GetAniString(ani_env *env, const string &str)
331 {
332     ani_string aniMimeType = nullptr;
333     const char *utf8String = str.c_str();
334     const ani_size stringLength = strlen(utf8String);
335     env->String_NewUTF8(utf8String, stringLength, &aniMimeType);
336     return aniMimeType;
337 }
338 
GetRecordSetMethod(ani_env * env,ani_object & argumentObj)339 ani_method ImageAniUtils::GetRecordSetMethod(ani_env* env, ani_object &argumentObj)
340 {
341     ani_status status;
342     ani_class recordCls;
343     status = env->FindClass("Lescompat/Record;", &recordCls);
344     if (status != ANI_OK) {
345         IMAGE_LOGE("FindClass failed status :%{public}u", status);
346         return nullptr;
347     }
348     ani_method ctor;
349     status = env->Class_FindMethod(recordCls, "<ctor>", nullptr, &ctor);
350     if (status != ANI_OK) {
351         IMAGE_LOGE("Class_FindMethod failed status :%{public}u", status);
352         return nullptr;
353     }
354     if (ANI_OK != env->Object_New(recordCls, ctor, &argumentObj)) {
355         IMAGE_LOGE("Object_New Failed");
356         return nullptr;
357     }
358     ani_method recordSetMethod;
359     status = env->Class_FindMethod(recordCls, "$_set",
360         "Lstd/core/Object;Lstd/core/Object;:V", &recordSetMethod);
361     if (status != ANI_OK) {
362         IMAGE_LOGE("Class_FindMethod recordSetMethod Failed");
363         return nullptr;
364     }
365     return recordSetMethod;
366 }
367 } // Meida
368 } // OHOS