forked from floraachy/ImageKnife
172 lines
6.5 KiB
C++
172 lines
6.5 KiB
C++
/*
|
|
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
//
|
|
// Created on 2022/12/21.
|
|
//
|
|
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
|
|
|
|
#ifndef GPU_ImageETS_NativeImage_H
|
|
#define GPU_ImageETS_NativeImage_H
|
|
|
|
#include <stdint.h>
|
|
#include <malloc.h>
|
|
#include <js_native_api.h>
|
|
#include <js_native_api_types.h>
|
|
#include <node_api.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include "DebugLog.h"
|
|
#include "constant/constant_shape.h"
|
|
#include "third_party_bounds_checking_function/include/securec.h"
|
|
|
|
#define IMAGE_FORMAT_RGBA 0x01
|
|
#define IMAGE_FORMAT_NV21 0x02
|
|
#define IMAGE_FORMAT_NV12 0x03
|
|
#define IMAGE_FORMAT_I420 0x04
|
|
#define IMAGE_FORMAT_YUYV 0x05
|
|
#define IMAGE_FORMAT_GRAY 0x06
|
|
#define IMAGE_FORMAT_I444 0x07
|
|
#define IMAGE_FORMAT_P010 0x08
|
|
|
|
#define IMAGE_FORMAT_RGBA_EXT "RGB32"
|
|
#define IMAGE_FORMAT_NV21_EXT "NV21"
|
|
#define IMAGE_FORMAT_NV12_EXT "NV12"
|
|
#define IMAGE_FORMAT_I420_EXT "I420"
|
|
#define IMAGE_FORMAT_YUYV_EXT "YUYV"
|
|
#define IMAGE_FORMAT_GRAY_EXT "GRAY"
|
|
#define IMAGE_FORMAT_I444_EXT "I444"
|
|
#define IMAGE_FORMAT_P010_EXT "P010" // 16bit NV21
|
|
#define EOK 0
|
|
|
|
struct NativeImage {
|
|
int width;
|
|
int height;
|
|
int format;
|
|
uint8_t *ppPlane[DEFAULT_THREE];
|
|
|
|
NativeImage()
|
|
{
|
|
width = DEFAULT_ZERO;
|
|
height = DEFAULT_ZERO;
|
|
format = DEFAULT_ZERO;
|
|
ppPlane[DEFAULT_ZERO] = nullptr;
|
|
ppPlane[DEFAULT_ONE] = nullptr;
|
|
ppPlane[DEFAULT_TWO] = nullptr;
|
|
}
|
|
};
|
|
|
|
class NativeImageUtil {
|
|
public:
|
|
static void AllocNativeImage(NativeImage *pImage)
|
|
{
|
|
if (pImage ->height == DEFAULT_ZERO || pImage ->width == DEFAULT_ZERO) return;
|
|
switch (pImage -> format) {
|
|
case IMAGE_FORMAT_RGBA: {
|
|
pImage->ppPlane[DEFAULT_ZERO] =
|
|
static_cast<uint8_t *>(malloc(pImage->width * pImage ->height * DEFAULT_FOUR));
|
|
}
|
|
break;
|
|
case IMAGE_FORMAT_YUYV: {
|
|
pImage->ppPlane[DEFAULT_ZERO] =
|
|
static_cast<uint8_t *>(malloc(pImage->width * pImage ->height * DEFAULT_TWO));
|
|
}
|
|
break;
|
|
case IMAGE_FORMAT_NV12:
|
|
case IMAGE_FORMAT_NV21: {
|
|
pImage->ppPlane[DEFAULT_ZERO] =
|
|
static_cast<uint8_t *>(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF));
|
|
pImage->ppPlane[DEFAULT_ONE] =
|
|
pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height;
|
|
}
|
|
break;
|
|
case IMAGE_FORMAT_I420: {
|
|
pImage->ppPlane[DEFAULT_ZERO] =
|
|
static_cast<uint8_t *>(malloc(pImage->width * pImage ->height * DEFAULT_ONE_HALF));
|
|
pImage->ppPlane[DEFAULT_ONE] =
|
|
pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height;
|
|
pImage->ppPlane[DEFAULT_TWO] =
|
|
pImage->ppPlane[DEFAULT_ONE] + pImage->width * (pImage->height >> DEFAULT_TWO);
|
|
}
|
|
break;
|
|
case IMAGE_FORMAT_GRAY: {
|
|
pImage->ppPlane[DEFAULT_ZERO] =
|
|
static_cast<uint8_t *>(malloc(pImage->width * pImage ->height));
|
|
}
|
|
break;
|
|
case IMAGE_FORMAT_I444: {
|
|
pImage->ppPlane[DEFAULT_ZERO] =
|
|
static_cast<uint8_t *>(malloc(pImage->width * pImage ->height * DEFAULT_THREE));
|
|
}
|
|
break;
|
|
case IMAGE_FORMAT_P010: {
|
|
pImage->ppPlane[DEFAULT_ZERO] =
|
|
static_cast<uint8_t *>(malloc(pImage->width * pImage ->height * DEFAULT_THREE));
|
|
pImage->ppPlane[DEFAULT_ONE] =
|
|
pImage->ppPlane[DEFAULT_ZERO] + pImage->width * pImage->height * DEFAULT_TWO;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void FreeNativeImage(NativeImage *pImage)
|
|
{
|
|
if (pImage == nullptr || pImage->ppPlane[DEFAULT_ZERO] == nullptr) return;
|
|
free(pImage->ppPlane[DEFAULT_ZERO]);
|
|
pImage->ppPlane[DEFAULT_ZERO] = nullptr;
|
|
pImage->ppPlane[DEFAULT_ONE] = nullptr;
|
|
pImage->ppPlane[DEFAULT_TWO] = nullptr;
|
|
}
|
|
|
|
static bool CreateArrayBuffer(napi_env env, void* src, size_t srcLen, napi_value *res)
|
|
{
|
|
if (src == nullptr || srcLen == DEFAULT_ZERO) {
|
|
return false;
|
|
}
|
|
void *nativePtr = nullptr;
|
|
if (napi_create_arraybuffer(env, srcLen, &nativePtr, res) != napi_ok || nativePtr == nullptr) {
|
|
return false;
|
|
}
|
|
if (memcpy_s(nativePtr, srcLen, src, srcLen) != EOK) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void Flip(uint8_t** buf, int width, int height)
|
|
{
|
|
int totalLength = width * height * DEFAULT_FOUR;
|
|
int oneLineLength = width * DEFAULT_FOUR;
|
|
uint8_t* tmp = (uint8_t*)malloc(totalLength);
|
|
if (memcpy_s(tmp, totalLength, *buf, totalLength) != EOK) {
|
|
return;
|
|
}
|
|
if (memset_s(*buf, sizeof(uint8_t)*totalLength, DEFAULT_ZERO, sizeof(uint8_t)*totalLength) != EOK) {
|
|
return;
|
|
}
|
|
for (int i = 0; i < height; i++) {
|
|
if (memcpy_s(*buf + oneLineLength * i, oneLineLength,
|
|
tmp + totalLength - oneLineLength * (i+1), oneLineLength) != EOK) {
|
|
break;
|
|
}
|
|
}
|
|
free(tmp);
|
|
}
|
|
};
|
|
|
|
#endif // GPU_ImageETS_NativeImage_H
|