• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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