/* * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved * * 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. */ #include "face.h" #include "face_priv.h" #include 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("Buffer Cannot be NULL. %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