diff options
Diffstat (limited to 'src/face_image.c')
-rwxr-xr-x | src/face_image.c | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/src/face_image.c b/src/face_image.c new file mode 100755 index 0000000..bd7e20d --- /dev/null +++ b/src/face_image.c @@ -0,0 +1,253 @@ +#include "face.h" +#include "face_priv.h" + +#include <stdlib.h> + + + +static void convert_RGB565_to_Y(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height) +{ + unsigned char* pDst, * pEnd; + unsigned short* pSrc; + + unsigned short R, G, B; + long lt; + + pSrc = (unsigned short*) pBuf; + pDst = (unsigned char*) pGrayBuf; + pEnd = (unsigned char*) ((unsigned char*) pGrayBuf + height * width); + + while (pDst < pEnd) + { + R = (unsigned char) ((*pSrc >> 11) << 3); // R + G = (unsigned char) ((*pSrc & 0x07e0) >> 3); // +G + B = (unsigned char) ((*pSrc++ & 0x001f) << 3); // +B + + // Y = 0.299 R + 0.587 G + 0.114 B + lt = (306L * (long) R + 601L * (long) G + 117L * (long) B); + *pDst++ = (unsigned char ) (lt >> 10); + //(BYTE)(((int)R+(int)G+(int)B) /3); + } +} + +static void convert_RGBA8888_to_Y(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height) +{ + unsigned long* pSrc = (unsigned long*) pBuf; + unsigned char* pDSt = (unsigned char*) pGrayBuf; + unsigned char* pEnd = pDSt + height * width; + + while (pDSt < pEnd) + { + unsigned long r = (*pSrc >> 16) & 0xFF; + unsigned long g = (*pSrc >> 8) & 0xFF; + unsigned long b = (*pSrc++) & 0xFF; + + *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10; + } +} + +#define CLIP(a) ((a) > 255 ? 255 : (a) < 0 ? 0 : (a)) + +#if 0 +static void convert_RGB888_to_Y(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height) +{ + unsigned char* pSrc = (unsigned char*) pBuf; + unsigned char* pDSt = (unsigned char*) pGrayBuf; + + unsigned char* pEnd = pDSt + height * width; + + while (pDSt < pEnd) + { + unsigned long r = *pSrc++; + unsigned long g = *pSrc++; + unsigned long b = *pSrc++; + + *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10; + } +} +#endif + +static bool _validate_face_image_h(face_image_h face_image) +{ + if ( face_image == NULL ) + { + return false; + } + + if ( face_image->magic != FACE_IMAGE_MAGIC ) + { + return false; + } + + return true; +} + + +EXPORT_API int face_image_create(__in face_image_colorspace_e colorspace, __in unsigned char *buffer, __in int width, __in int height, __in int size, __out face_image_h *face_image) +{ + if ( face_image == NULL ) + { + LOG_ERROR("Out pointer is NULL. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + if ( buffer == NULL ) + { + LOG_ERROR("Invalid image data. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + if ( width <= 0 || height <= 0 ) + { + LOG_ERROR("Invalid image size(%d,%d). %s", width, height, _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + unsigned char *YBuf = NULL; + + switch(colorspace) + { + case FACE_IMAGE_COLORSPACE_YUV420: + YBuf = buffer; + break; + + case FACE_IMAGE_COLORSPACE_RGB565: + YBuf = (unsigned char *)calloc(1, width * height); + if ( YBuf == NULL ) + { + LOG_ERROR("Cannot allocate FACE_IMAGE_COLORSPACE_RGB565 buffer"); + return FACE_ERROR_OUT_OF_MEMORY; + } + + convert_RGB565_to_Y(buffer, YBuf, width, height); + break; + + case FACE_IMAGE_COLORSPACE_RGBA8888: + YBuf = (unsigned char *)calloc(1, width * height); + if ( YBuf == NULL ) + { + LOG_ERROR("Cannot allocate FACE_IMAGE_COLORSPACE_RGBA8888 buffer"); + return FACE_ERROR_OUT_OF_MEMORY; + } + + convert_RGBA8888_to_Y(buffer, YBuf, width, height); + break; + + case FACE_IMAGE_COLORSPACE_LUMINANCE_ONLY: + YBuf = buffer; + break; + default: + LOG_ERROR("Invalid colorspace(%d). %s", colorspace, _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + *face_image = (FaceImage *)calloc(1, sizeof(FaceImage)); + + if ( *face_image == NULL ) + { + LOG_ERROR("Cannot allocate face_image_h"); + return FACE_ERROR_OUT_OF_MEMORY; + } + + (*face_image)->magic = FACE_IMAGE_MAGIC; + + (*face_image)->pixel = YBuf; + (*face_image)->width = width; + (*face_image)->height = height; + (*face_image)->size = width * height; + (*face_image)->colorspace = colorspace; + + return FACE_ERROR_NONE; +} + + +EXPORT_API int face_image_destroy(face_image_h face_image) +{ + if ( _validate_face_image_h(face_image) == false ) + { + LOG_ERROR("Invalid image handle. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + if ( face_image->colorspace == FACE_IMAGE_COLORSPACE_RGB565 || face_image->colorspace == FACE_IMAGE_COLORSPACE_RGBA8888) + { + free(face_image->pixel); // Free user buffer + } + + face_image->pixel = NULL; + face_image->magic = FACE_INVALID_MAGIC; + + free(face_image); + + return FACE_ERROR_NONE; +} + + +#if 0 +EXPORT_API int face_image_set_data( face_image_h face_image, + face_image_colorspace_e colorspace, unsigned char *buffer, int width, int height, int size) +{ + +// Check Param. + if ( _validate_face_image_h(face_image) == false ) + { + LOG_ERROR("Invalid image handle. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + if ( buffer == NULL ) + { + LOG_ERROR("Invalid image data. %s", width, height, _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + if ( width <= 0 || height <= 0 ) + { + LOG_ERROR("Invalid image size(%d,%d). %s", width, height, _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + if ( colorspace != FACE_IMAGE_COLORSPACE_LUMINANCE_ONLY) + { + LOG_ERROR("Invalid image format(%d). %s", colorspace , _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + face_image->pixel = buffer; + face_image->width = width; + face_image->height = height; + face_image->size = width * height; + face_image->colorspace = colorspace; + + return FACE_ERROR_NONE; + +} + + + +EXPORT_API int face_image_get_data(face_image_h face_image, + face_image_colorspace_e *colorspace, unsigned char **buffer, int *width, int *height, int *size) +{ + if ( _validate_face_image_h(face_image) == false ) + { + LOG_ERROR("Invalid image handle. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER)); + return FACE_ERROR_INVALID_PARAMTER; + } + + if ( colorspace == NULL || buffer == NULL || width == NULL || height == NULL ) + { + LOG_ERROR("Invalid param. 0x%08x 0x%08x 0x%08x 0x%08x", colorspace, buffer, width, height); + return FACE_ERROR_INVALID_PARAMTER; + } + + *buffer = face_image->pixel; + *width = face_image->width; + *height = face_image->height; + *colorspace = face_image->colorspace; + *size = face_image->size; + + return FACE_ERROR_NONE; +} +#endif + + |