2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 #include "face_priv.h"
24 static void convert_RGB565_to_Y(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height)
26 unsigned char* pDst, * pEnd;
29 unsigned short R, G, B;
32 pSrc = (unsigned short*) pBuf;
33 pDst = (unsigned char*) pGrayBuf;
34 pEnd = (unsigned char*) ((unsigned char*) pGrayBuf + height * width);
38 R = (unsigned char) ((*pSrc >> 11) << 3); // R
39 G = (unsigned char) ((*pSrc & 0x07e0) >> 3); // +G
40 B = (unsigned char) ((*pSrc++ & 0x001f) << 3); // +B
42 // Y = 0.299 R + 0.587 G + 0.114 B
43 lt = (306L * (long) R + 601L * (long) G + 117L * (long) B);
44 *pDst++ = (unsigned char ) (lt >> 10);
45 //(BYTE)(((int)R+(int)G+(int)B) /3);
49 static void convert_BGRA8888_to_Y(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height)
51 unsigned long* pSrc = (unsigned long*) pBuf;
52 unsigned char* pDSt = (unsigned char*) pGrayBuf;
53 unsigned char* pEnd = pDSt + height * width;
57 unsigned long r = (*pSrc >> 16) & 0xFF;
58 unsigned long g = (*pSrc >> 8) & 0xFF;
59 unsigned long b = (*pSrc++) & 0xFF;
61 *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10;
65 static void convert_RGBA8888_to_Y(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height)
67 unsigned long* pSrc = (unsigned long*) pBuf;
68 unsigned char* pDSt = (unsigned char*) pGrayBuf;
69 unsigned char* pEnd = pDSt + height * width;
73 unsigned long b = (*pSrc >> 16) & 0xFF;
74 unsigned long g = (*pSrc >> 8) & 0xFF;
75 unsigned long r = (*pSrc++) & 0xFF;
77 *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10;
81 #define CLIP(a) ((a) > 255 ? 255 : (a) < 0 ? 0 : (a))
84 static void convert_RGB888_to_Y(unsigned char* pBuf, unsigned char* pGrayBuf, int width, int height)
86 unsigned char* pSrc = (unsigned char*) pBuf;
87 unsigned char* pDSt = (unsigned char*) pGrayBuf;
89 unsigned char* pEnd = pDSt + height * width;
93 unsigned long r = *pSrc++;
94 unsigned long g = *pSrc++;
95 unsigned long b = *pSrc++;
97 *pDSt++ = (308 * r + 600 * g + 116 * b) >> 10;
102 static bool _validate_face_image_h(face_image_h face_image)
104 if ( face_image == NULL )
109 if ( face_image->magic != FACE_IMAGE_MAGIC )
118 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)
120 if ( face_image == NULL )
122 LOG_ERROR("Out pointer is NULL. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
123 return FACE_ERROR_INVALID_PARAMTER;
126 if ( buffer == NULL )
128 LOG_ERROR("Buffer Cannot be NULL. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
129 return FACE_ERROR_INVALID_PARAMTER;
132 if ( width <= 0 || height <= 0 )
134 LOG_ERROR("Invalid image size(%d,%d). %s", width, height, _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
135 return FACE_ERROR_INVALID_PARAMTER;
138 unsigned char *YBuf = NULL;
139 unsigned char *YBufRef = NULL;
143 case FACE_IMAGE_COLORSPACE_YUV420:
147 case FACE_IMAGE_COLORSPACE_RGB565:
148 YBufRef = YBuf = (unsigned char *)calloc(1, width * height);
151 LOG_ERROR("Cannot allocate FACE_IMAGE_COLORSPACE_RGB565 buffer");
152 return FACE_ERROR_OUT_OF_MEMORY;
155 convert_RGB565_to_Y(buffer, YBuf, width, height);
158 case FACE_IMAGE_COLORSPACE_BGRA8888:
159 YBufRef = YBuf = (unsigned char *)calloc(1, width * height);
162 LOG_ERROR("Cannot allocate FACE_IMAGE_COLORSPACE_BGRA8888 buffer");
163 return FACE_ERROR_OUT_OF_MEMORY;
166 convert_BGRA8888_to_Y(buffer, YBuf, width, height);
169 case FACE_IMAGE_COLORSPACE_RGBA8888:
170 YBufRef = YBuf = (unsigned char *)calloc(1, width * height);
173 LOG_ERROR("Cannot allocate FACE_IMAGE_COLORSPACE_RGBA8888 buffer");
174 return FACE_ERROR_OUT_OF_MEMORY;
177 convert_RGBA8888_to_Y(buffer, YBuf, width, height);
181 case FACE_IMAGE_COLORSPACE_LUMINANCE_ONLY:
185 LOG_ERROR("Invalid colorspace(%d). %s", colorspace, _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
186 return FACE_ERROR_INVALID_PARAMTER;
189 *face_image = (FaceImage *)calloc(1, sizeof(FaceImage));
191 if ( *face_image == NULL )
193 LOG_ERROR("Cannot allocate face_image_h");
194 if ( YBufRef != NULL )
199 return FACE_ERROR_OUT_OF_MEMORY;
202 (*face_image)->magic = FACE_IMAGE_MAGIC;
204 (*face_image)->pixel = YBuf;
205 (*face_image)->width = width;
206 (*face_image)->height = height;
207 (*face_image)->size = width * height;
208 (*face_image)->colorspace = colorspace;
210 return FACE_ERROR_NONE;
214 EXPORT_API int face_image_destroy(face_image_h face_image)
216 if ( _validate_face_image_h(face_image) == false )
218 LOG_ERROR("Invalid image handle. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
219 return FACE_ERROR_INVALID_PARAMTER;
222 if ( face_image->colorspace == FACE_IMAGE_COLORSPACE_RGB565 || face_image->colorspace == FACE_IMAGE_COLORSPACE_BGRA8888 || face_image->colorspace == FACE_IMAGE_COLORSPACE_RGBA8888 )
224 free(face_image->pixel); // Free user buffer
227 face_image->pixel = NULL;
228 face_image->magic = FACE_INVALID_MAGIC;
232 return FACE_ERROR_NONE;
237 EXPORT_API int face_image_set_data( face_image_h face_image,
238 face_image_colorspace_e colorspace, unsigned char *buffer, int width, int height, int size)
242 if ( _validate_face_image_h(face_image) == false )
244 LOG_ERROR("Invalid image handle. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
245 return FACE_ERROR_INVALID_PARAMTER;
248 if ( buffer == NULL )
250 LOG_ERROR("Invalid image data. %s", width, height, _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
251 return FACE_ERROR_INVALID_PARAMTER;
254 if ( width <= 0 || height <= 0 )
256 LOG_ERROR("Invalid image size(%d,%d). %s", width, height, _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
257 return FACE_ERROR_INVALID_PARAMTER;
260 if ( colorspace != FACE_IMAGE_COLORSPACE_LUMINANCE_ONLY)
262 LOG_ERROR("Invalid image format(%d). %s", colorspace , _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
263 return FACE_ERROR_INVALID_PARAMTER;
266 face_image->pixel = buffer;
267 face_image->width = width;
268 face_image->height = height;
269 face_image->size = width * height;
270 face_image->colorspace = colorspace;
272 return FACE_ERROR_NONE;
278 EXPORT_API int face_image_get_data(face_image_h face_image,
279 face_image_colorspace_e *colorspace, unsigned char **buffer, int *width, int *height, int *size)
281 if ( _validate_face_image_h(face_image) == false )
283 LOG_ERROR("Invalid image handle. %s", _face_convert_error(FACE_ERROR_INVALID_PARAMTER));
284 return FACE_ERROR_INVALID_PARAMTER;
287 if ( colorspace == NULL || buffer == NULL || width == NULL || height == NULL )
289 LOG_ERROR("Invalid param. 0x%08x 0x%08x 0x%08x 0x%08x", colorspace, buffer, width, height);
290 return FACE_ERROR_INVALID_PARAMTER;
293 *buffer = face_image->pixel;
294 *width = face_image->width;
295 *height = face_image->height;
296 *colorspace = face_image->colorspace;
297 *size = face_image->size;
299 return FACE_ERROR_NONE;