1 /*
2  * Copyright (C) 2023 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_receiver_mdk_kits.h"
17 #include "image_receiver_napi_listener.h"
18 #include "image_napi.h"
19 
20 #include <map>
21 
22 namespace OHOS {
23 namespace Media {
24 using ImageReceiverNapiEnvFunc = int32_t (*)(napi_env env, struct ImageReceiverArgs* args);
25 using ImageReceiverNapiCtxFunc = int32_t (*)(ImageReceiverNapi* native, struct ImageReceiverArgs* args);
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
GetNativeReceiver(ImageReceiverNapi * napi)29 static ImageReceiver* GetNativeReceiver(ImageReceiverNapi* napi)
30 {
31     if (napi == nullptr) {
32         return nullptr;
33     }
34     return napi->GetNative();
35 }
36 
CheckAndGetReceiver(ImageReceiverNapi * native,const struct ImageReceiverArgs * args)37 static ImageReceiver* CheckAndGetReceiver(ImageReceiverNapi* native, const struct ImageReceiverArgs* args)
38 {
39     if (args == nullptr) {
40         return nullptr;
41     }
42     return GetNativeReceiver(native);
43 }
44 
ImageReceiverNapiCreate(napi_env env,struct ImageReceiverArgs * args)45 static int32_t ImageReceiverNapiCreate(napi_env env, struct ImageReceiverArgs* args)
46 {
47     if (args == nullptr) {
48         return IMAGE_RESULT_JNI_ENV_ABNORMAL;
49     }
50 
51     ImageReceiverCreateArgs createArgs;
52     createArgs.width = args->inNum0;
53     createArgs.height = args->inNum1;
54     createArgs.format = args->inNum2;
55     createArgs.capicity = args->inNum3;
56     *(args->outValue) = ImageReceiverNapi::CreateImageReceiverJsObject(env, createArgs);
57     if (*(args->outValue) == nullptr) {
58         return IMAGE_RESULT_BAD_PARAMETER;
59     }
60     return IMAGE_RESULT_SUCCESS;
61 }
62 
ImageReceiverNapiGetReceiverId(ImageReceiverNapi * native,struct ImageReceiverArgs * args)63 static int32_t ImageReceiverNapiGetReceiverId(ImageReceiverNapi* native, struct ImageReceiverArgs* args)
64 {
65     auto receiver = CheckAndGetReceiver(native, args);
66     if (receiver == nullptr || receiver->iraContext_ == nullptr || args->id == nullptr) {
67         return IMAGE_RESULT_BAD_PARAMETER;
68     }
69     auto sId = receiver->iraContext_->GetReceiverKey();
70     if (sId.empty() || sId.c_str() == nullptr || args->inLen < sId.size()) {
71         return IMAGE_RESULT_BAD_PARAMETER;
72     }
73     if (EOK != memcpy_s(args->id, args->inLen, sId.c_str(), sId.size())) {
74         return IMAGE_RESULT_BAD_PARAMETER;
75     }
76     return IMAGE_RESULT_SUCCESS;
77 }
78 
ImageReceiverNapiReadLatestImage(ImageReceiverNapi * native,struct ImageReceiverArgs * args)79 static int32_t ImageReceiverNapiReadLatestImage(ImageReceiverNapi* native, struct ImageReceiverArgs* args)
80 {
81     auto receiver = CheckAndGetReceiver(native, args);
82     if (receiver == nullptr || args->inEnv == nullptr) {
83         return IMAGE_RESULT_JNI_ENV_ABNORMAL;
84     }
85     auto image = receiver->LastNativeImage();
86     if (image == nullptr) {
87         return IMAGE_RESULT_BAD_PARAMETER;
88     }
89     *(args->outValue) = ImageNapi::Create(args->inEnv, image);
90     return IMAGE_RESULT_SUCCESS;
91 }
92 
ImageReceiverNapiReadNextImage(ImageReceiverNapi * native,struct ImageReceiverArgs * args)93 static int32_t ImageReceiverNapiReadNextImage(ImageReceiverNapi* native, struct ImageReceiverArgs* args)
94 {
95     auto receiver = CheckAndGetReceiver(native, args);
96     if (receiver == nullptr || args->inEnv == nullptr) {
97         return IMAGE_RESULT_JNI_ENV_ABNORMAL;
98     }
99     auto image = receiver->NextNativeImage();
100     if (image == nullptr) {
101         return IMAGE_RESULT_BAD_PARAMETER;
102     }
103     *(args->outValue) = ImageNapi::Create(args->inEnv, image);
104     return IMAGE_RESULT_SUCCESS;
105 }
106 
ImageReceiverNapiOn(ImageReceiverNapi * native,struct ImageReceiverArgs * args)107 static int32_t ImageReceiverNapiOn(ImageReceiverNapi* native, struct ImageReceiverArgs* args)
108 {
109     auto receiver = CheckAndGetReceiver(native, args);
110     if (receiver == nullptr || args->callback == nullptr) {
111         return IMAGE_RESULT_JNI_ENV_ABNORMAL;
112     }
113     std::shared_ptr<ImageReceiverNapiListener> listener = std::make_shared<ImageReceiverNapiListener>();
114     listener->callBack = args->callback;
115     receiver->RegisterBufferAvaliableListener(listener);
116     return IMAGE_RESULT_SUCCESS;
117 }
118 
ImageReceiverNapiGetSize(ImageReceiverNapi * native,struct ImageReceiverArgs * args)119 static int32_t ImageReceiverNapiGetSize(ImageReceiverNapi* native, struct ImageReceiverArgs* args)
120 {
121     auto receiver = CheckAndGetReceiver(native, args);
122     if (receiver == nullptr || receiver->iraContext_ == nullptr || args->outSize == nullptr) {
123         return IMAGE_RESULT_JNI_ENV_ABNORMAL;
124     }
125     args->outSize->width = receiver->iraContext_->GetWidth();
126     args->outSize->height = receiver->iraContext_->GetHeight();
127     return IMAGE_RESULT_SUCCESS;
128 }
129 
ImageReceiverNapiGetCapacity(ImageReceiverNapi * native,struct ImageReceiverArgs * args)130 static int32_t ImageReceiverNapiGetCapacity(ImageReceiverNapi* native, struct ImageReceiverArgs* args)
131 {
132     auto receiver = CheckAndGetReceiver(native, args);
133     if (receiver == nullptr || receiver->iraContext_ == nullptr) {
134         return IMAGE_RESULT_JNI_ENV_ABNORMAL;
135     }
136     *(args->outNum0) = receiver->iraContext_->GetCapicity();
137     return IMAGE_RESULT_SUCCESS;
138 }
139 
ImageReceiverNapiGetFormat(ImageReceiverNapi * native,struct ImageReceiverArgs * args)140 static int32_t ImageReceiverNapiGetFormat(ImageReceiverNapi* native, struct ImageReceiverArgs* args)
141 {
142     auto receiver = CheckAndGetReceiver(native, args);
143     if (receiver == nullptr || receiver->iraContext_ == nullptr) {
144         return IMAGE_RESULT_JNI_ENV_ABNORMAL;
145     }
146     *(args->outNum0) = receiver->iraContext_->GetFormat();
147     return IMAGE_RESULT_SUCCESS;
148 }
149 static const std::map<int32_t, ImageReceiverNapiEnvFunc> g_EnvFunctions = {
150     {ENV_FUNC_IMAGE_RECEIVER_CREATE, ImageReceiverNapiCreate},
151 };
152 static const std::map<int32_t, ImageReceiverNapiCtxFunc> g_CtxFunctions = {
153     {CTX_FUNC_IMAGE_RECEIVER_GET_RECEIVER_ID, ImageReceiverNapiGetReceiverId},
154     {CTX_FUNC_IMAGE_RECEIVER_READ_LATEST_IMAGE, ImageReceiverNapiReadLatestImage},
155     {CTX_FUNC_IMAGE_RECEIVER_READ_NEXT_IMAGE, ImageReceiverNapiReadNextImage},
156     {CTX_FUNC_IMAGE_RECEIVER_ON, ImageReceiverNapiOn},
157     {CTX_FUNC_IMAGE_RECEIVER_GET_SIZE, ImageReceiverNapiGetSize},
158     {CTX_FUNC_IMAGE_RECEIVER_GET_CAPACITY, ImageReceiverNapiGetCapacity},
159     {CTX_FUNC_IMAGE_RECEIVER_GET_FORMAT, ImageReceiverNapiGetFormat},
160 };
161 
162 MIDK_EXPORT
ImageReceiverNativeEnvCall(int32_t mode,napi_env env,struct ImageReceiverArgs * args)163 int32_t ImageReceiverNativeEnvCall(int32_t mode, napi_env env, struct ImageReceiverArgs* args)
164 {
165     auto funcSearch = g_EnvFunctions.find(mode);
166     if (funcSearch == g_EnvFunctions.end()) {
167         return IMAGE_RESULT_BAD_PARAMETER;
168     }
169     return funcSearch->second(env, args);
170 }
171 
172 MIDK_EXPORT
ImageReceiverNativeCtxCall(int32_t mode,ImageReceiverNapi * native,struct ImageReceiverArgs * args)173 int32_t ImageReceiverNativeCtxCall(int32_t mode, ImageReceiverNapi* native, struct ImageReceiverArgs* args)
174 {
175     auto funcSearch = g_CtxFunctions.find(mode);
176     if (funcSearch == g_CtxFunctions.end()) {
177         return IMAGE_RESULT_BAD_PARAMETER;
178     }
179     return funcSearch->second(native, args);
180 }
181 
182 MIDK_EXPORT
ImageReceiver_Unwrap(napi_env env,napi_value value)183 ImageReceiverNapi* ImageReceiver_Unwrap(napi_env env, napi_value value)
184 {
185     napi_valuetype valueType;
186     napi_typeof(env, value, &valueType);
187     if (valueType != napi_object) {
188         return nullptr;
189     }
190     std::unique_ptr<ImageReceiverNapi> receiverNapi = nullptr;
191     napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&receiverNapi));
192     if ((status == napi_ok) && receiverNapi != nullptr) {
193         return receiverNapi.release();
194     }
195     return nullptr;
196 }
197 #ifdef __cplusplus
198 };
199 #endif
200 }  // namespace Media
201 }  // namespace OHOS
202