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