1 /*
2 * Copyright (C) 2022 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_pixel_map_napi_kits.h"
17
18 #include <map>
19 #include <set>
20 #include "pixel_map_napi.h"
21
22 namespace {
23 constexpr uint32_t NUM_0 = 0;
24 constexpr uint32_t NUM_1 = 1;
25 }
26
27 namespace OHOS {
28 namespace Media {
29 using PixelMapNapiEnvFunc = int32_t (*)(napi_env env, PixelMapNapiArgs* args);
30 using PixelMapNapiCtxFunc = int32_t (*)(PixelMapNapi* native, PixelMapNapiArgs* args);
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
makeUndefined(napi_env env,napi_value * value)35 static bool makeUndefined(napi_env env, napi_value* value)
36 {
37 if (env != nullptr) {
38 napi_get_undefined(env, value);
39 return true;
40 }
41 return false;
42 }
43
isUndefine(napi_env env,napi_value value)44 static bool isUndefine(napi_env env, napi_value value)
45 {
46 napi_valuetype res = napi_undefined;
47 napi_typeof(env, value, &res);
48 return (res == napi_undefined);
49 }
50
GetPixelMap(PixelMapNapi * napi,PixelMapNapiArgs * args,int32_t & error)51 static std::shared_ptr<PixelMap> GetPixelMap(PixelMapNapi* napi, PixelMapNapiArgs* args,
52 int32_t &error)
53 {
54 if (napi == nullptr || napi->GetPixelNapiInner() == nullptr) {
55 error = IMAGE_RESULT_DATA_ABNORMAL;
56 return nullptr;
57 }
58 return napi->GetPixelNapiInner();
59 }
60
ParsePixelForamt(int32_t val)61 static PixelFormat ParsePixelForamt(int32_t val)
62 {
63 if (val < static_cast<int32_t>(PixelFormat::EXTERNAL_MAX)) {
64 return PixelFormat(val);
65 }
66
67 return PixelFormat::UNKNOWN;
68 }
ParseAlphaType(int32_t val)69 static AlphaType ParseAlphaType(int32_t val)
70 {
71 if (val <= static_cast<int32_t>(AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL)) {
72 return AlphaType(val);
73 }
74
75 return AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN;
76 }
77
ParseScaleMode(int32_t val)78 static ScaleMode ParseScaleMode(int32_t val)
79 {
80 if (val <= static_cast<int32_t>(ScaleMode::CENTER_CROP)) {
81 return ScaleMode(val);
82 }
83
84 return ScaleMode::FIT_TARGET_SIZE;
85 }
86
ParseAntiAliasingOption(int32_t val)87 static AntiAliasingOption ParseAntiAliasingOption(int32_t val)
88 {
89 if (val <= static_cast<int32_t>(AntiAliasingOption::SPLINE)) {
90 return AntiAliasingOption(val);
91 }
92
93 return AntiAliasingOption::NONE;
94 }
95
PixelMapNapiCreate(napi_env env,PixelMapNapiArgs * args)96 static int32_t PixelMapNapiCreate(napi_env env, PixelMapNapiArgs* args)
97 {
98 if (args == nullptr || args->outValue == nullptr) {
99 return IMAGE_RESULT_INVALID_PARAMETER;
100 }
101 napi_value undefinedValue = nullptr;
102 if ((!makeUndefined(env, &undefinedValue)) || args->inBuffer == nullptr || args->bufferLen <= NUM_0) {
103 *(args->outValue) = undefinedValue;
104 return IMAGE_RESULT_GET_DATA_ABNORMAL;
105 }
106
107 *(args->outValue) = undefinedValue;
108 InitializationOptions info;
109 info.alphaType = ParseAlphaType(args->createOptions.alphaType);
110 info.editable = args->createOptions.editable != NUM_0;
111 info.pixelFormat = ParsePixelForamt(args->createOptions.pixelFormat);
112 info.scaleMode = ParseScaleMode(args->createOptions.scaleMode);
113 info.srcRowStride = args->rowStride;
114 info.useDMA = args->useDMA;
115 info.size.height = static_cast<int32_t>(args->createOptions.height);
116 info.size.width = static_cast<int32_t>(args->createOptions.width);
117
118 BUILD_PARAM pam;
119 pam.offset_ = 0;
120 pam.width_ = info.size.width;
121 pam.flag_ = false;
122 int32_t error = IMAGE_RESULT_SUCCESS;
123 if (info.pixelFormat == PixelFormat::RGBA_1010102 ||
124 info.pixelFormat == PixelFormat::YCBCR_P010 ||
125 info.pixelFormat == PixelFormat::YCRCB_P010) {
126 error = IMAGE_RESULT_BAD_PARAMETER;
127 return error;
128 }
129 auto pixelmap = PixelMap::Create(static_cast<uint32_t*>(args->inBuffer), args->bufferLen, pam, info, error);
130 if (pixelmap == nullptr) {
131 return error;
132 }
133
134 *(args->outValue) = PixelMapNapi::CreatePixelMap(env, std::move(pixelmap));
135 return isUndefine(env, *(args->outValue))?IMAGE_RESULT_BAD_PARAMETER:IMAGE_RESULT_SUCCESS;
136 }
137
PixelMapNapiCreateAlpha(napi_env env,PixelMapNapiArgs * args)138 static int32_t PixelMapNapiCreateAlpha(napi_env env, PixelMapNapiArgs* args)
139 {
140 if (args == nullptr || args->outValue == nullptr) {
141 return IMAGE_RESULT_INVALID_PARAMETER;
142 }
143 napi_value undefinedValue = nullptr;
144 if ((!makeUndefined(env, &undefinedValue)) || args->inValue == nullptr) {
145 *(args->outValue) = undefinedValue;
146 return IMAGE_RESULT_GET_DATA_ABNORMAL;
147 }
148 *(args->outValue) = undefinedValue;
149
150 auto pixelmap = PixelMapNapi::GetPixelMap(env, args->inValue);
151 if (pixelmap == nullptr) {
152 return IMAGE_RESULT_BAD_PARAMETER;
153 }
154
155 InitializationOptions opts;
156 opts.pixelFormat = PixelFormat::ALPHA_8;
157 Rect rect;
158 int32_t error = IMAGE_RESULT_SUCCESS;
159 auto alphaPixelMap = PixelMap::Create(*pixelmap, rect, opts, error);
160 if (alphaPixelMap == nullptr) {
161 return error;
162 }
163
164 *(args->outValue) = PixelMapNapi::CreatePixelMap(env, std::move(alphaPixelMap));
165 return isUndefine(env, *(args->outValue))?IMAGE_RESULT_BAD_PARAMETER:IMAGE_RESULT_SUCCESS;
166 }
167
CheckAndGetPixelMap(PixelMapNapi * native,PixelMapNapiArgs * args,int32_t error)168 static std::shared_ptr<PixelMap> CheckAndGetPixelMap(PixelMapNapi* native, PixelMapNapiArgs* args,
169 int32_t error)
170 {
171 return args == nullptr ? nullptr : GetPixelMap(native, args, error);
172 }
173
PixelMapNapiGetRowBytes(PixelMapNapi * native,PixelMapNapiArgs * args)174 static int32_t PixelMapNapiGetRowBytes(PixelMapNapi* native, PixelMapNapiArgs* args)
175 {
176 int32_t error = IMAGE_RESULT_SUCCESS;
177 auto pixelmap = CheckAndGetPixelMap(native, args, error);
178 if (pixelmap == nullptr) {
179 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
180 }
181 *(args->outNum) = pixelmap->GetRowBytes();
182 return IMAGE_RESULT_SUCCESS;
183 }
184
PixelMapNapiIsEditable(PixelMapNapi * native,PixelMapNapiArgs * args)185 static int32_t PixelMapNapiIsEditable(PixelMapNapi* native, PixelMapNapiArgs* args)
186 {
187 int32_t error = IMAGE_RESULT_SUCCESS;
188 auto pixelmap = CheckAndGetPixelMap(native, args, error);
189 if (pixelmap == nullptr) {
190 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
191 }
192
193 *(args->outNum) = pixelmap->IsEditable();
194 return IMAGE_RESULT_SUCCESS;
195 }
196
PixelMapNapiIsSupportAlpha(PixelMapNapi * native,PixelMapNapiArgs * args)197 static int32_t PixelMapNapiIsSupportAlpha(PixelMapNapi* native, PixelMapNapiArgs* args)
198 {
199 int32_t error = IMAGE_RESULT_SUCCESS;
200 auto pixelmap = CheckAndGetPixelMap(native, args, error);
201 if (pixelmap == nullptr) {
202 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
203 }
204
205 *(args->outNum) = pixelmap->GetAlphaType() != AlphaType::IMAGE_ALPHA_TYPE_OPAQUE;
206 return IMAGE_RESULT_SUCCESS;
207 }
208
PixelMapNapiSetAlphaAble(PixelMapNapi * native,PixelMapNapiArgs * args)209 static int32_t PixelMapNapiSetAlphaAble(PixelMapNapi* native, PixelMapNapiArgs* args)
210 {
211 int32_t error = IMAGE_RESULT_SUCCESS;
212 auto pixelmap = CheckAndGetPixelMap(native, args, error);
213 if (pixelmap == nullptr) {
214 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
215 }
216
217 auto alphaType = pixelmap->GetAlphaType();
218 if ((args->inNum0 != NUM_0) && (alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
219 pixelmap->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_PREMUL);
220 } else if ((args->inNum0 == NUM_0) && !(alphaType == AlphaType::IMAGE_ALPHA_TYPE_OPAQUE)) {
221 pixelmap->SetAlphaType(AlphaType::IMAGE_ALPHA_TYPE_OPAQUE);
222 } else {
223 return IMAGE_RESULT_BAD_PARAMETER;
224 }
225
226 return IMAGE_RESULT_SUCCESS;
227 }
228
PixelMapNapiGetDensity(PixelMapNapi * native,PixelMapNapiArgs * args)229 static int32_t PixelMapNapiGetDensity(PixelMapNapi* native, PixelMapNapiArgs* args)
230 {
231 int32_t error = IMAGE_RESULT_SUCCESS;
232 auto pixelmap = CheckAndGetPixelMap(native, args, error);
233 if (pixelmap == nullptr) {
234 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
235 }
236
237 *(args->outNum) = pixelmap->GetBaseDensity();
238 return IMAGE_RESULT_SUCCESS;
239 }
240
PixelMapNapiSetDensity(PixelMapNapi * native,PixelMapNapiArgs * args)241 static int32_t PixelMapNapiSetDensity(PixelMapNapi* native, PixelMapNapiArgs* args)
242 {
243 int32_t error = IMAGE_RESULT_SUCCESS;
244 auto pixelmap = CheckAndGetPixelMap(native, args, error);
245 if (pixelmap == nullptr) {
246 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
247 }
248
249 ImageInfo imageinfo;
250 pixelmap->GetImageInfo(imageinfo);
251 if (imageinfo.baseDensity != args->inNum0) {
252 imageinfo.baseDensity = args->inNum0;
253 if (pixelmap->SetImageInfo(imageinfo, true) != IMAGE_RESULT_SUCCESS) {
254 return IMAGE_RESULT_INDEX_INVALID;
255 }
256 }
257 return IMAGE_RESULT_SUCCESS;
258 }
259
PixelMapNapiSetOpacity(PixelMapNapi * native,PixelMapNapiArgs * args)260 static int32_t PixelMapNapiSetOpacity(PixelMapNapi* native, PixelMapNapiArgs* args)
261 {
262 int32_t error = IMAGE_RESULT_SUCCESS;
263 auto pixelmap = CheckAndGetPixelMap(native, args, error);
264 if (pixelmap == nullptr) {
265 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
266 }
267
268 if (pixelmap->SetAlpha(args->inFloat0) != IMAGE_RESULT_SUCCESS) {
269 return IMAGE_RESULT_BAD_PARAMETER;
270 }
271 return IMAGE_RESULT_SUCCESS;
272 }
273
PixelMapNapiScale(PixelMapNapi * native,PixelMapNapiArgs * args)274 static int32_t PixelMapNapiScale(PixelMapNapi* native, PixelMapNapiArgs* args)
275 {
276 int32_t error = IMAGE_RESULT_SUCCESS;
277 auto pixelmap = CheckAndGetPixelMap(native, args, error);
278 if (pixelmap == nullptr) {
279 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
280 }
281
282 if (args->inNum0 == static_cast<int32_t>(AntiAliasingOption::NONE)) {
283 pixelmap->scale(args->inFloat0, args->inFloat1);
284 } else {
285 pixelmap->scale(args->inFloat0, args->inFloat1, ParseAntiAliasingOption(args->inNum0));
286 }
287 return pixelmap->errorCode == 0 ? IMAGE_RESULT_SUCCESS : pixelmap->errorCode;
288 }
289
PixelMapNapiTranslate(PixelMapNapi * native,PixelMapNapiArgs * args)290 static int32_t PixelMapNapiTranslate(PixelMapNapi* native, PixelMapNapiArgs* args)
291 {
292 int32_t error = IMAGE_RESULT_SUCCESS;
293 auto pixelmap = CheckAndGetPixelMap(native, args, error);
294 if (pixelmap == nullptr) {
295 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
296 }
297
298 pixelmap->translate(args->inFloat0, args->inFloat1);
299 return pixelmap->errorCode == 0 ? IMAGE_RESULT_SUCCESS : pixelmap->errorCode;
300 }
301
PixelMapNapiRotate(PixelMapNapi * native,PixelMapNapiArgs * args)302 static int32_t PixelMapNapiRotate(PixelMapNapi* native, PixelMapNapiArgs* args)
303 {
304 int32_t error = IMAGE_RESULT_SUCCESS;
305 auto pixelmap = CheckAndGetPixelMap(native, args, error);
306 if (pixelmap == nullptr) {
307 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
308 }
309
310 pixelmap->rotate(args->inFloat0);
311 return pixelmap->errorCode == 0 ? IMAGE_RESULT_SUCCESS : pixelmap->errorCode;
312 }
313
PixelMapNapiFlip(PixelMapNapi * native,PixelMapNapiArgs * args)314 static int32_t PixelMapNapiFlip(PixelMapNapi* native, PixelMapNapiArgs* args)
315 {
316 int32_t error = IMAGE_RESULT_SUCCESS;
317 auto pixelmap = CheckAndGetPixelMap(native, args, error);
318 if (pixelmap == nullptr) {
319 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
320 }
321
322 pixelmap->flip((args->inNum0 == NUM_1), (args->inNum1 == NUM_1));
323 return pixelmap->errorCode == 0 ? IMAGE_RESULT_SUCCESS : pixelmap->errorCode;
324 }
325
PixelMapNapiCrop(PixelMapNapi * native,PixelMapNapiArgs * args)326 static int32_t PixelMapNapiCrop(PixelMapNapi* native, PixelMapNapiArgs* args)
327 {
328 int32_t error = IMAGE_RESULT_SUCCESS;
329 auto pixelmap = CheckAndGetPixelMap(native, args, error);
330 if (pixelmap == nullptr) {
331 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
332 }
333 Rect region;
334 region.left = args->inNum0;
335 region.top = args->inNum1;
336 region.width = args->inNum2;
337 region.height = args->inNum3;
338 pixelmap->crop(region);
339 return pixelmap->errorCode == 0 ? IMAGE_RESULT_SUCCESS : pixelmap->errorCode;
340 }
341
PixelMapNapiGetImageInfo(PixelMapNapi * native,PixelMapNapiArgs * args)342 static int32_t PixelMapNapiGetImageInfo(PixelMapNapi* native, PixelMapNapiArgs* args)
343 {
344 int32_t error = IMAGE_RESULT_SUCCESS;
345 auto pixelmap = CheckAndGetPixelMap(native, args, error);
346 if (pixelmap == nullptr || args->outInfo == nullptr) {
347 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
348 }
349
350 ImageInfo srcInfo;
351 pixelmap->GetImageInfo(srcInfo);
352 args->outInfo->width = static_cast<uint32_t>(srcInfo.size.width);
353 args->outInfo->height = static_cast<uint32_t>(srcInfo.size.height);
354 args->outInfo->rowSize = static_cast<uint32_t>(pixelmap->GetRowStride());
355 args->outInfo->pixelFormat = static_cast<int32_t>(srcInfo.pixelFormat);
356 return pixelmap->errorCode == 0 ? IMAGE_RESULT_SUCCESS : pixelmap->errorCode;
357 }
358
PixelMapNapiAccessPixels(PixelMapNapi * native,PixelMapNapiArgs * args)359 static int32_t PixelMapNapiAccessPixels(PixelMapNapi* native, PixelMapNapiArgs* args)
360 {
361 int32_t error = IMAGE_RESULT_SUCCESS;
362 auto pixelmap = CheckAndGetPixelMap(native, args, error);
363 if (pixelmap == nullptr) {
364 return error != 0 ? error : IMAGE_RESULT_INVALID_PARAMETER;
365 }
366 native->LockPixelMap();
367 *(args->outAddr) = static_cast<uint8_t*>(pixelmap->GetWritablePixels());
368 return pixelmap->errorCode == 0 ? IMAGE_RESULT_SUCCESS : pixelmap->errorCode;
369 }
370
PixelMapNapiUnAccessPixels(PixelMapNapi * native,PixelMapNapiArgs * args)371 static int32_t PixelMapNapiUnAccessPixels(PixelMapNapi* native, PixelMapNapiArgs* args)
372 {
373 if (native != nullptr) {
374 native->UnlockPixelMap();
375 return IMAGE_RESULT_SUCCESS;
376 } else {
377 return IMAGE_RESULT_INVALID_PARAMETER;
378 }
379 }
380
381 static const std::map<int32_t, PixelMapNapiEnvFunc> g_EnvFunctions = {
382 {ENV_FUNC_CREATE, PixelMapNapiCreate},
383 {ENV_FUNC_CREATE_ALPHA, PixelMapNapiCreateAlpha},
384 };
385 static const std::map<int32_t, PixelMapNapiCtxFunc> g_CtxFunctions = {
386 {CTX_FUNC_GET_ROW_BYTES, PixelMapNapiGetRowBytes},
387 {CTX_FUNC_IS_EDITABLE, PixelMapNapiIsEditable},
388 {CTX_FUNC_IS_SUPPORT_ALPHA, PixelMapNapiIsSupportAlpha},
389 {CTX_FUNC_GET_DENSITY, PixelMapNapiGetDensity},
390 {CTX_FUNC_SET_ALPHAABLE, PixelMapNapiSetAlphaAble},
391 {CTX_FUNC_SET_DENSITY, PixelMapNapiSetDensity},
392 {CTX_FUNC_SET_OPACITY, PixelMapNapiSetOpacity},
393 {CTX_FUNC_SCALE, PixelMapNapiScale},
394 {CTX_FUNC_TRANSLATE, PixelMapNapiTranslate},
395 {CTX_FUNC_ROTATE, PixelMapNapiRotate},
396 {CTX_FUNC_FLIP, PixelMapNapiFlip},
397 {CTX_FUNC_CROP, PixelMapNapiCrop},
398 {CTX_FUNC_GET_IMAGE_INFO, PixelMapNapiGetImageInfo},
399 {CTX_FUNC_ACCESS_PIXELS, PixelMapNapiAccessPixels},
400 {CTX_FUNC_UNACCESS_PIXELS, PixelMapNapiUnAccessPixels},
401 };
402
403 MIDK_EXPORT
PixelMapNapiNativeEnvCall(int32_t mode,napi_env env,PixelMapNapiArgs * args)404 int32_t PixelMapNapiNativeEnvCall(int32_t mode, napi_env env, PixelMapNapiArgs* args)
405 {
406 auto funcSearch = g_EnvFunctions.find(mode);
407 if (funcSearch == g_EnvFunctions.end()) {
408 return IMAGE_RESULT_JNI_ENV_ABNORMAL;
409 }
410 return funcSearch->second(env, args);
411 }
412
413 MIDK_EXPORT
PixelMapNapiNativeCtxCall(int32_t mode,PixelMapNapi * native,PixelMapNapiArgs * args)414 int32_t PixelMapNapiNativeCtxCall(int32_t mode, PixelMapNapi* native, PixelMapNapiArgs* args)
415 {
416 auto funcSearch = g_CtxFunctions.find(mode);
417 if (funcSearch == g_CtxFunctions.end()) {
418 return IMAGE_RESULT_JNI_ENV_ABNORMAL;
419 }
420 return funcSearch->second(native, args);
421 }
422
423 MIDK_EXPORT
PixelMapNapi_Unwrap(napi_env env,napi_value value)424 PixelMapNapi* PixelMapNapi_Unwrap(napi_env env, napi_value value)
425 {
426 napi_valuetype valueType;
427 napi_typeof(env, value, &valueType);
428 if (valueType != napi_object) {
429 return nullptr;
430 }
431 std::unique_ptr<PixelMapNapi> pixelMapNapi = nullptr;
432 napi_status status = napi_unwrap(env, value, reinterpret_cast<void**>(&pixelMapNapi));
433 if ((status == napi_ok) && pixelMapNapi != nullptr) {
434 return pixelMapNapi.release();
435 }
436 return nullptr;
437 }
438 #ifdef __cplusplus
439 };
440 #endif
441 } // namespace Media
442 } // namespace OHOS
443