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.
19 #include <mm_util_imgp.h>
20 #include <mm_util_jpeg.h>
21 #include <mm_util_imgcv.h>
22 #include <mm_util_png.h>
23 #include <mm_util_gif.h>
24 #include <mm_util_bmp.h>
25 #include <image_util.h>
26 #include <image_util_private.h>
30 #define IMAGE_UTIL_STRING_VALID(str) \
31 ((str != NULL && strlen(str) > 0) ? true : false)
33 #define IMAGE_UTIL_SAFE_FREE(src) { if (src) {free(src); src = NULL; } }
35 static int _convert_colorspace_tbl[] = {
36 MM_UTIL_IMG_FMT_YUV420, /* IMAGE_UTIL_COLORSPACE_YUV420 */
37 MM_UTIL_IMG_FMT_YUV422, /* IMAGE_UTIL_COLORSPACE_YUV422 */
38 MM_UTIL_IMG_FMT_I420, /* IMAGE_UTIL_COLORSPACE_I420 */
39 MM_UTIL_IMG_FMT_NV12, /* IMAGE_UTIL_COLORSPACE_NV12 */
40 MM_UTIL_IMG_FMT_UYVY, /* IMAGE_UTIL_COLORSPACE_UYVY */
41 MM_UTIL_IMG_FMT_YUYV, /* IMAGE_UTIL_COLORSPACE_YUYV */
42 MM_UTIL_IMG_FMT_RGB565, /* IMAGE_UTIL_COLORSPACE_RGB565 */
43 MM_UTIL_IMG_FMT_RGB888, /* IMAGE_UTIL_COLORSPACE_RGB888 */
44 MM_UTIL_IMG_FMT_ARGB8888, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
45 MM_UTIL_IMG_FMT_BGRA8888, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
46 MM_UTIL_IMG_FMT_RGBA8888, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
47 MM_UTIL_IMG_FMT_BGRX8888, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
48 MM_UTIL_JPEG_FMT_NV21, /* IMAGE_UTIL_COLORSPACE_NV12 */
49 MM_UTIL_JPEG_FMT_NV16, /* IMAGE_UTIL_COLORSPACE_NV16 */
50 MM_UTIL_JPEG_FMT_NV61, /* IMAGE_UTIL_COLORSPACE_NV61 */
53 static int _convert_encode_colorspace_tbl[] = {
54 MM_UTIL_JPEG_FMT_YUV420, /* IMAGE_UTIL_COLORSPACE_YUV420 */
55 -1, /* IMAGE_UTIL_COLORSPACE_YUV422 */
56 MM_UTIL_JPEG_FMT_YUV420, /* IMAGE_UTIL_COLORSPACE_I420 */
57 MM_UTIL_JPEG_FMT_NV12, /* IMAGE_UTIL_COLORSPACE_NV12 */
58 -1, /* IMAGE_UTIL_COLORSPACE_UYVY */
59 -1, /* IMAGE_UTIL_COLORSPACE_YUYV */
60 -1, /* IMAGE_UTIL_COLORSPACE_RGB565 */
61 MM_UTIL_JPEG_FMT_RGB888, /* IMAGE_UTIL_COLORSPACE_RGB888 */
62 MM_UTIL_JPEG_FMT_ARGB8888, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
63 MM_UTIL_JPEG_FMT_BGRA8888, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
64 MM_UTIL_JPEG_FMT_RGBA8888, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
65 -1, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
66 -1, /* IMAGE_UTIL_COLORSPACE_NV21 */
67 -1, /* IMAGE_UTIL_COLORSPACE_NV16 */
68 -1, /* IMAGE_UTIL_COLORSPACE_NV61 */
71 static int _convert_jpeg_colorspace_tbl[] = {
72 MM_UTIL_JPEG_FMT_YUV420, /* IMAGE_UTIL_COLORSPACE_YUV420 */
73 -1, /* IMAGE_UTIL_COLORSPACE_YUV422 */
74 MM_UTIL_JPEG_FMT_YUV420, /* IMAGE_UTIL_COLORSPACE_I420 */
75 MM_UTIL_JPEG_FMT_NV12, /* IMAGE_UTIL_COLORSPACE_NV12 */
76 -1, /* IMAGE_UTIL_COLORSPACE_UYVY */
77 -1, /* IMAGE_UTIL_COLORSPACE_YUYV */
78 -1, /* IMAGE_UTIL_COLORSPACE_RGB565 */
79 MM_UTIL_JPEG_FMT_RGB888, /* IMAGE_UTIL_COLORSPACE_RGB888 */
80 MM_UTIL_JPEG_FMT_ARGB8888, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
81 MM_UTIL_JPEG_FMT_BGRA8888, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
82 MM_UTIL_JPEG_FMT_RGBA8888, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
83 -1, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
84 -1, /* IMAGE_UTIL_COLORSPACE_NV21 */
85 -1, /* IMAGE_UTIL_COLORSPACE_NV16 */
86 -1, /* IMAGE_UTIL_COLORSPACE_NV61 */
89 static int _convert_png_colorspace_tbl[] = {
90 -1, /* IMAGE_UTIL_COLORSPACE_YUV420 */
91 -1, /* IMAGE_UTIL_COLORSPACE_YUV422 */
92 -1, /* IMAGE_UTIL_COLORSPACE_I420 */
93 -1, /* IMAGE_UTIL_COLORSPACE_NV12 */
94 -1, /* IMAGE_UTIL_COLORSPACE_UYVY */
95 -1, /* IMAGE_UTIL_COLORSPACE_YUYV */
96 -1, /* IMAGE_UTIL_COLORSPACE_RGB565 */
97 -1, /* IMAGE_UTIL_COLORSPACE_RGB888 */
98 -1, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
99 -1, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
100 MM_UTIL_PNG_COLOR_TYPE_RGB_ALPHA, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
101 -1, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
102 -1, /* IMAGE_UTIL_COLORSPACE_NV21 */
103 -1, /* IMAGE_UTIL_COLORSPACE_NV16 */
104 -1, /* IMAGE_UTIL_COLORSPACE_NV61 */
107 static int _convert_gif_colorspace_tbl[] = {
108 -1, /* IMAGE_UTIL_COLORSPACE_YUV420 */
109 -1, /* IMAGE_UTIL_COLORSPACE_YUV422 */
110 -1, /* IMAGE_UTIL_COLORSPACE_I420 */
111 -1, /* IMAGE_UTIL_COLORSPACE_NV12 */
112 -1, /* IMAGE_UTIL_COLORSPACE_UYVY */
113 -1, /* IMAGE_UTIL_COLORSPACE_YUYV */
114 -1, /* IMAGE_UTIL_COLORSPACE_RGB565 */
115 -1, /* IMAGE_UTIL_COLORSPACE_RGB888 */
116 -1, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
117 -1, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
118 MM_UTIL_GIF_FMT_RGBA8888, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
119 -1, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
120 -1, /* IMAGE_UTIL_COLORSPACE_NV21 */
121 -1, /* IMAGE_UTIL_COLORSPACE_NV16 */
122 -1, /* IMAGE_UTIL_COLORSPACE_NV61 */
125 static int _convert_bmp_colorspace_tbl[] = {
126 -1, /* IMAGE_UTIL_COLORSPACE_YUV420 */
127 -1, /* IMAGE_UTIL_COLORSPACE_YUV422 */
128 -1, /* IMAGE_UTIL_COLORSPACE_I420 */
129 -1, /* IMAGE_UTIL_COLORSPACE_NV12 */
130 -1, /* IMAGE_UTIL_COLORSPACE_UYVY */
131 -1, /* IMAGE_UTIL_COLORSPACE_YUYV */
132 -1, /* IMAGE_UTIL_COLORSPACE_RGB565 */
133 -1, /* IMAGE_UTIL_COLORSPACE_RGB888 */
134 -1, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
135 -1, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
136 MM_UTIL_BMP_FMT_RGBA8888, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
137 -1, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
138 -1, /* IMAGE_UTIL_COLORSPACE_NV21 */
139 -1, /* IMAGE_UTIL_COLORSPACE_NV16 */
140 -1, /* IMAGE_UTIL_COLORSPACE_NV61 */
143 static int _convert_decode_scale_tbl[] = {
144 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1,
145 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_2,
146 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_4,
147 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_8,
150 static int _convert_image_util_error_code(const char *func, int code)
152 int ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
153 char *errorstr = NULL;
155 case MM_UTIL_ERROR_NONE:
156 ret = IMAGE_UTIL_ERROR_NONE;
157 errorstr = strdup("ERROR_NONE");
159 case MM_UTIL_ERROR_NO_SUCH_FILE:
160 ret = IMAGE_UTIL_ERROR_NO_SUCH_FILE;
161 errorstr = strdup("NO_SUCH_FILE");
163 case MM_UTIL_ERROR_INVALID_PARAMETER:
164 ret = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
165 errorstr = strdup("INVALID_PARAMETER");
167 case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
168 ret = IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
169 errorstr = strdup("NOT_SUPPORTED_FORMAT");
171 case MM_UTIL_ERROR_OUT_OF_MEMORY:
172 ret = IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
173 errorstr = strdup("OUT_OF_MEMORY");
175 case MM_UTIL_ERROR_INVALID_OPERATION:
177 ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
178 errorstr = strdup("INVALID_OPERATION");
182 image_util_debug("[%s] %s(0x%08x)", func, errorstr, ret);
183 IMAGE_UTIL_SAFE_FREE(errorstr);
187 static image_util_error_e _image_util_error_convert(int error)
190 case MM_UTIL_ERROR_NONE:
191 image_util_debug("Error None");
192 return IMAGE_UTIL_ERROR_NONE;
193 case MM_UTIL_ERROR_INVALID_PARAMETER:
194 image_util_error("INVALID_PARAMETER(0x%08x)", IMAGE_UTIL_ERROR_INVALID_PARAMETER);
195 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
196 case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
197 image_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
198 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
199 case MM_UTIL_ERROR_OUT_OF_MEMORY:
200 image_util_error("OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
201 return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
203 case MM_UTIL_ERROR_INVALID_OPERATION:
205 image_util_error("INVALID_OPERATION(0x%08x)", error);
206 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
210 static void _image_util_transform_completed_cb(media_packet_h * dst, int error, void *user_data)
212 int error_value = IMAGE_UTIL_ERROR_NONE;
213 image_util_cb_s *_util_cb = (image_util_cb_s *) user_data;
215 if ((_util_cb != NULL) && (_util_cb->image_processing_completed_cb != NULL)) {
216 error_value = _image_util_error_convert(error);
217 _util_cb->image_processing_completed_cb(dst, error_value, _util_cb->user_data);
223 static int _image_util_create_transform_handle(transformation_s * handle)
225 int err = MM_UTIL_ERROR_NONE;
226 MMHandleType image_h;
228 err = mm_util_create(&image_h);
229 if (err != MM_UTIL_ERROR_NONE) {
230 image_util_error("Error - mm_util_create");
231 return _convert_image_util_error_code(__func__, err);
234 handle->image_h = image_h;
236 return _convert_image_util_error_code(__func__, err);
239 static bool _image_util_check_resolution(int width, int height)
242 image_util_error("invalid width [%d]", width);
247 image_util_error("invalid height [%d]", height);
254 int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void *user_data)
258 image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
260 /* RGB has higher precedence than YUV */
261 for (i = sizeof(_convert_encode_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
262 if (_convert_encode_colorspace_tbl[i] != -1)
263 if (false == callback(i, user_data))
264 return IMAGE_UTIL_ERROR_NONE;
268 return IMAGE_UTIL_ERROR_NONE;
271 int image_util_transform_create(transformation_h * handle)
273 int err = MM_UTIL_ERROR_NONE;
275 image_util_debug("image_util_create");
277 image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
279 transformation_s *_handle = (transformation_s *) calloc(1, sizeof(transformation_s));
280 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
282 _handle->colorspace = -1;
283 _handle->_util_cb = NULL;
284 _handle->image_h = 0;
285 _handle->hardware_acceleration = false;
286 _handle->set_convert = false;
287 _handle->set_resize = false;
288 _handle->set_rotate = false;
289 _handle->set_crop = false;
291 err = _image_util_create_transform_handle(_handle);
292 if (err != MM_UTIL_ERROR_NONE) {
293 image_util_error("Error - create transform handle");
294 IMAGE_UTIL_SAFE_FREE(_handle);
295 return _convert_image_util_error_code(__func__, err);
298 *handle = (transformation_h) _handle;
300 return _convert_image_util_error_code(__func__, err);
303 int image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
305 int err = MM_UTIL_ERROR_NONE;
306 transformation_s *_handle = (transformation_s *) handle;
308 image_util_debug("Set hardware_acceleration %d", mode);
310 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
311 #ifndef ENABLE_HW_ACCELERATION
312 image_util_retvm_if((mode == true), IMAGE_UTIL_ERROR_NOT_SUPPORTED, "hardware acceleration is not supported");
315 err = mm_util_set_hardware_acceleration(_handle->image_h, mode);
316 if (err != MM_UTIL_ERROR_NONE) {
317 image_util_error("Error - Set hardware_acceleration");
318 return _convert_image_util_error_code(__func__, err);
321 image_util_debug("Set hardware_acceleration %d", mode);
322 _handle->hardware_acceleration = mode;
324 return _convert_image_util_error_code(__func__, err);
327 int image_util_transform_set_colorspace(transformation_h handle, image_util_colorspace_e colorspace)
329 int err = MM_UTIL_ERROR_NONE;
330 transformation_s *_handle = (transformation_s *) handle;
332 image_util_debug("Set colorspace_convert_info [%d]", colorspace);
334 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
336 err = mm_util_set_colorspace_convert(_handle->image_h, colorspace);
337 if (err != MM_UTIL_ERROR_NONE) {
338 image_util_error("Error - Set colorspace convert");
339 return _convert_image_util_error_code(__func__, err);
342 _handle->colorspace = colorspace;
343 _handle->set_convert = true;
345 return _convert_image_util_error_code(__func__, err);
348 int image_util_transform_set_resolution(transformation_h handle, unsigned int width, unsigned int height)
350 int err = MM_UTIL_ERROR_NONE;
351 transformation_s *_handle = (transformation_s *) handle;
353 image_util_debug("Set resize_info w[%d] h[%d]", width, height);
355 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
356 image_util_retvm_if((_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
357 image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
359 err = mm_util_set_resolution(_handle->image_h, width, height);
360 if (err != MM_UTIL_ERROR_NONE) {
361 image_util_error("Error - Set resolution");
362 return _convert_image_util_error_code(__func__, err);
364 _handle->width = width;
365 _handle->height = height;
366 _handle->set_resize = true;
368 return _convert_image_util_error_code(__func__, err);
371 int image_util_transform_set_rotation(transformation_h handle, image_util_rotation_e rotation)
373 int err = MM_UTIL_ERROR_NONE;
374 transformation_s *_handle = (transformation_s *) handle;
376 image_util_debug("Set rotate_info [%d]", rotation);
378 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
380 err = mm_util_set_rotation(_handle->image_h, rotation);
381 if (err != MM_UTIL_ERROR_NONE) {
382 image_util_error("Error - Set rotation");
383 return _convert_image_util_error_code(__func__, err);
385 _handle->rotation = rotation;
386 _handle->set_rotate = true;
388 return _convert_image_util_error_code(__func__, err);
391 int image_util_transform_set_crop_area(transformation_h handle, unsigned int start_x, unsigned int start_y, unsigned int end_x, unsigned int end_y)
393 int err = MM_UTIL_ERROR_NONE;
394 transformation_s *_handle = (transformation_s *) handle;
398 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
399 image_util_retvm_if((_handle->set_resize), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
401 dest_width = end_x - start_x;
402 dest_height = end_y - start_y;
404 image_util_debug("Set crop_info x[%d] y[%d] w[%d] h[%d]", start_x, start_y, dest_width, dest_height);
406 image_util_retvm_if((_image_util_check_resolution(dest_width, dest_height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest resolution");
407 err = mm_util_set_crop_area(_handle->image_h, start_x, start_y, end_x, end_y);
408 if (err != MM_UTIL_ERROR_NONE) {
409 image_util_error("Error - Set crop area");
410 return _convert_image_util_error_code(__func__, err);
412 _handle->start_x = start_x;
413 _handle->start_y = start_y;
414 _handle->end_x = end_x;
415 _handle->end_y = end_y;
416 _handle->set_crop = true;
418 return _convert_image_util_error_code(__func__, err);
421 int image_util_transform_get_colorspace(transformation_h handle, image_util_colorspace_e * colorspace)
423 int ret = IMAGE_UTIL_ERROR_NONE;
424 transformation_s *_handle = (transformation_s *) handle;
426 image_util_debug("Get colorspace_convert_info [%d]", colorspace);
428 if (_handle == NULL) {
429 image_util_error("Invalid Handle");
430 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
434 image_util_error("colorspace area parameter error");
435 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
438 if (!_handle->set_convert) {
439 image_util_error("Did not set colorspace before");
440 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
443 *colorspace = _handle->colorspace;
447 int image_util_transform_get_resolution(transformation_h handle, unsigned int *width, unsigned int *height)
449 int ret = IMAGE_UTIL_ERROR_NONE;
450 transformation_s *_handle = (transformation_s *) handle;
452 image_util_debug("Set resize_info w[%d] h[%d]", width, height);
454 if (_handle == NULL) {
455 image_util_error("Invalid Handle");
456 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
459 if (!width || !height) {
460 image_util_error("resolution area parameter error");
461 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
464 if (!_handle->set_resize) {
465 image_util_error("Did not set resolution before");
466 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
469 *width = _handle->width;
470 *height = _handle->height;
475 int image_util_transform_get_rotation(transformation_h handle, image_util_rotation_e * rotation)
477 int ret = IMAGE_UTIL_ERROR_NONE;
478 transformation_s *_handle = (transformation_s *) handle;
480 image_util_debug("Set rotate_info [%d]", rotation);
482 if (_handle == NULL) {
483 image_util_error("Invalid Handle");
484 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
488 image_util_error("rotation area parameter error");
489 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
492 if (!_handle->set_rotate) {
493 image_util_error("Did not set rotation before");
494 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
497 *rotation = _handle->rotation;
502 int image_util_transform_get_crop_area(transformation_h handle, unsigned int *start_x, unsigned int *start_y, unsigned int *end_x, unsigned int *end_y)
504 int ret = IMAGE_UTIL_ERROR_NONE;
505 transformation_s *_handle = (transformation_s *) handle;
507 if (_handle == NULL) {
508 image_util_error("Invalid Handle");
509 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
512 if (!start_x || !start_y || !end_x || !end_y) {
513 image_util_error("crop area parameter error");
514 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
517 if (!_handle->set_crop) {
518 image_util_error("Did not set crop area before");
519 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
522 *start_x = _handle->start_x;
523 *start_y = _handle->start_y;
524 *end_x = _handle->end_x;
525 *end_y = _handle->end_y;
530 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
532 int err = MM_UTIL_ERROR_NONE;
533 transformation_s *_handle = (transformation_s *) handle;
535 image_util_debug("image_util_transform");
537 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
538 image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
539 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source");
540 image_util_retvm_if((!_handle->set_convert && !_handle->set_resize && !_handle->set_rotate && !_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform");
542 if (_handle->_util_cb != NULL) {
543 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
544 _handle->_util_cb = NULL;
546 _handle->_util_cb = (image_util_cb_s *) calloc(1, sizeof(image_util_cb_s));
547 image_util_retvm_if((_handle->_util_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
549 _handle->_util_cb->user_data = user_data;
550 _handle->_util_cb->image_processing_completed_cb = completed_cb;
552 if (_handle->_util_cb)
553 err = mm_util_transform(_handle->image_h, src, (mm_util_completed_callback) _image_util_transform_completed_cb, (void *)_handle->_util_cb);
555 return _convert_image_util_error_code(__func__, err);
558 int image_util_transform_destroy(transformation_h handle)
560 int err = MM_UTIL_ERROR_NONE;
561 transformation_s *_handle = (transformation_s *) handle;
563 image_util_debug("image_util_destroy");
565 if (_handle == NULL) {
566 image_util_error("Invalid Handle");
567 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
570 err = mm_util_destroy(_handle->image_h);
572 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
573 IMAGE_UTIL_SAFE_FREE(_handle);
575 return _convert_image_util_error_code(__func__, err);
578 int image_util_convert_colorspace(unsigned char *dest, image_util_colorspace_e dest_colorspace, const unsigned char *src, int width, int height, image_util_colorspace_e src_colorspace)
580 int err = MM_UTIL_ERROR_NONE;
582 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
583 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
584 image_util_retvm_if((dest_colorspace < 0 || dest_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dst_colorspace");
585 image_util_retvm_if((src_colorspace < 0 || src_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid src_colorspace");
587 err = mm_util_convert_colorspace(src, width, height, _convert_colorspace_tbl[src_colorspace], dest, _convert_colorspace_tbl[dest_colorspace]);
589 return _convert_image_util_error_code(__func__, err);
592 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace, unsigned int *size)
594 int err = MM_UTIL_ERROR_NONE;
596 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
597 image_util_retvm_if((width <= 0 || height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid width or Invalid height");
598 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
600 err = mm_util_get_image_size(_convert_colorspace_tbl[colorspace], width, height, size);
601 return _convert_image_util_error_code(__func__, err);
604 int image_util_resize(unsigned char *dest, int *dest_width, int *dest_height, const unsigned char *src, int src_width, int src_height, image_util_colorspace_e colorspace)
606 int err = MM_UTIL_ERROR_NONE;
608 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
609 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
610 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
611 image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
612 image_util_retvm_if((*dest_width <= 0 || *dest_height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest_width or Invalid dest_height");
614 unsigned int dest_w, dest_h;
615 dest_w = *dest_width;
616 dest_h = *dest_height;
617 err = mm_util_resize_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h);
618 if (err == MM_UTIL_ERROR_NONE) {
619 *dest_width = (int)dest_w;
620 *dest_height = (int)dest_h;
623 return _convert_image_util_error_code(__func__, err);
626 int image_util_rotate(unsigned char *dest, int *dest_width, int *dest_height, image_util_rotation_e dest_rotation, const unsigned char *src, int src_width, int src_height, image_util_colorspace_e colorspace)
628 int err = MM_UTIL_ERROR_NONE;
630 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
631 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
632 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
633 image_util_retvm_if((dest_rotation < 0 || dest_rotation > IMAGE_UTIL_ROTATION_FLIP_VERT), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid rotation");
634 image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
636 unsigned int dest_w, dest_h;
637 err = mm_util_rotate_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h, dest_rotation);
638 if (err == MM_UTIL_ERROR_NONE) {
639 *dest_width = (int)dest_w;
640 *dest_height = (int)dest_h;
642 return _convert_image_util_error_code(__func__, err);
645 int image_util_crop(unsigned char *dest, int x, int y, int *width, int *height, const unsigned char *src, int src_width, int src_height, image_util_colorspace_e colorspace)
647 int err = MM_UTIL_ERROR_NONE;
649 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
650 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
651 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
652 image_util_retvm_if((width == NULL || height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "width or height is null");
653 image_util_retvm_if((src_width <= x || src_height <= y || src_width < x + *width || src_height < y + *height), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid crop area");
655 unsigned int dest_w, dest_h;
658 err = mm_util_crop_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], x, y, &dest_w, &dest_h, dest);
659 if (err == MM_UTIL_ERROR_NONE) {
660 *width = (int)dest_w;
661 *height = (int)dest_h;
664 return _convert_image_util_error_code(__func__, err);
667 int image_util_decode_jpeg(const char *path, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
669 int err = MM_UTIL_ERROR_NONE;
671 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
672 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
673 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
674 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
675 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
676 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
678 mm_util_jpeg_yuv_data decoded;
679 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
681 err = mm_util_decode_from_jpeg_file(&decoded, path, _convert_encode_colorspace_tbl[colorspace]);
682 if (err == MM_UTIL_ERROR_NONE) {
683 *image_buffer = decoded.data;
685 *width = decoded.width;
687 *height = decoded.height;
689 *size = (unsigned int)decoded.size;
691 return _convert_image_util_error_code(__func__, err);
694 int image_util_decode_jpeg_from_memory(const unsigned char *jpeg_buffer, int jpeg_size, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
696 int err = MM_UTIL_ERROR_NONE;
698 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
699 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
700 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
701 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
702 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
704 mm_util_jpeg_yuv_data decoded;
705 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
707 err = mm_util_decode_from_jpeg_memory(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace]);
709 if (err == MM_UTIL_ERROR_NONE) {
710 *image_buffer = decoded.data;
712 *width = decoded.width;
714 *height = decoded.height;
716 *size = (unsigned int)decoded.size;
719 return _convert_image_util_error_code(__func__, err);
722 int image_util_decode_jpeg_with_downscale(const char *path, image_util_colorspace_e colorspace, image_util_scale_e downscale, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
724 int err = MM_UTIL_ERROR_NONE;
726 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
727 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
728 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
729 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
730 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
731 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
732 image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
734 mm_util_jpeg_yuv_data decoded;
735 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
737 err = mm_util_decode_from_jpeg_file_with_downscale(&decoded, path, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
738 if (err == MM_UTIL_ERROR_NONE) {
739 *image_buffer = decoded.data;
741 *width = decoded.width;
743 *height = decoded.height;
745 *size = (unsigned int)decoded.size;
747 return _convert_image_util_error_code(__func__, err);
750 int image_util_decode_jpeg_from_memory_with_downscale(const unsigned char *jpeg_buffer, int jpeg_size, image_util_colorspace_e colorspace, image_util_scale_e downscale, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
752 int err = MM_UTIL_ERROR_NONE;
754 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
755 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
756 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
757 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
758 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
759 image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
761 mm_util_jpeg_yuv_data decoded;
762 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
764 err = mm_util_decode_from_jpeg_memory_with_downscale(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
766 if (err == MM_UTIL_ERROR_NONE) {
767 *image_buffer = decoded.data;
769 *width = decoded.width;
771 *height = decoded.height;
773 *size = (unsigned int)decoded.size;
776 return _convert_image_util_error_code(__func__, err);
779 int image_util_encode_jpeg(const unsigned char *buffer, int width, int height, image_util_colorspace_e colorspace, int quality, const char *path)
781 int err = MM_UTIL_ERROR_NONE;
783 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
784 image_util_retvm_if((buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "buffer is null");
785 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
786 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
787 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
789 err = mm_util_jpeg_encode_to_file(path, (void *)buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
790 return _convert_image_util_error_code(__func__, err);
793 int image_util_encode_jpeg_to_memory(const unsigned char *image_buffer, int width, int height, image_util_colorspace_e colorspace, int quality, unsigned char **jpeg_buffer, unsigned int *jpeg_size)
795 int err = MM_UTIL_ERROR_NONE;
798 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
799 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
800 image_util_retvm_if((jpeg_size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_size is null");
801 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
802 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
804 err = mm_util_jpeg_encode_to_memory((void **)jpeg_buffer, &isize, (void *)image_buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
805 if (err == MM_UTIL_ERROR_NONE)
806 *jpeg_size = (unsigned int)isize;
808 return _convert_image_util_error_code(__func__, err);
811 int image_util_extract_color_from_memory(const unsigned char *image_buffer, int width, int height, unsigned char *rgb_r, unsigned char *rgb_g, unsigned char *rgb_b)
813 int ret = MM_UTIL_ERROR_NONE;
815 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
817 unsigned char r_color, g_color, b_color;
818 ret = mm_util_cv_extract_representative_color((void *)image_buffer, width, height, &r_color, &g_color, &b_color);
824 return _convert_image_util_error_code(__func__, ret);
827 int image_util_foreach_supported_colorspace(image_util_type_e image_type, image_util_supported_colorspace_cb callback, void *user_data)
831 image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
833 switch (image_type) {
834 case IMAGE_UTIL_JPEG:
835 /* RGB has higher precedence than YUV */
836 for (i = sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
837 if (_convert_jpeg_colorspace_tbl[i] != -1)
838 if (false == callback(i, user_data))
839 return IMAGE_UTIL_ERROR_NONE;
844 for (i = sizeof(_convert_png_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
845 if (_convert_png_colorspace_tbl[i] != -1)
846 if (false == callback(i, user_data))
847 return IMAGE_UTIL_ERROR_NONE;
852 for (i = sizeof(_convert_gif_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
853 if (_convert_gif_colorspace_tbl[i] != -1)
854 if (false == callback(i, user_data))
855 return IMAGE_UTIL_ERROR_NONE;
860 for (i = sizeof(_convert_bmp_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
861 if (_convert_bmp_colorspace_tbl[i] != -1)
862 if (false == callback(i, user_data))
863 return IMAGE_UTIL_ERROR_NONE;
868 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
871 return IMAGE_UTIL_ERROR_NONE;
874 static int _image_util_decode_create_jpeg_handle(decode_encode_s * handle)
876 int err = MM_UTIL_ERROR_NONE;
878 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
880 mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data));
881 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
883 handle->image_h = (MMHandleType) _handle;
884 handle->colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888;
885 handle->down_scale = sizeof(image_util_scale_e);
890 static int _image_util_decode_create_png_handle(decode_encode_s * handle)
892 int err = MM_UTIL_ERROR_NONE;
894 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
896 mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data));
897 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
899 mm_util_init_decode_png(_handle);
901 handle->image_h = (MMHandleType) _handle;
906 static int _image_util_decode_create_gif_handle(decode_encode_s * handle)
908 int err = MM_UTIL_ERROR_NONE;
910 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
912 mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data));
913 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
915 handle->image_h = (MMHandleType) _handle;
920 static int _image_util_decode_create_bmp_handle(decode_encode_s * handle)
922 int err = MM_UTIL_ERROR_NONE;
924 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
926 mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data));
927 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
929 handle->image_h = (MMHandleType) _handle;
934 int image_util_decode_create(image_util_decode_h * handle)
936 int err = MM_UTIL_ERROR_NONE;
938 image_util_debug("image_util_decode_create");
940 image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
942 decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
943 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
945 _handle->src_buffer = NULL;
946 _handle->dst_buffer = NULL;
947 _handle->path = NULL;
948 _handle->image_h = 0;
949 _handle->is_decode = TRUE;
950 _handle->image_type = -1;
952 *handle = (image_util_decode_h) _handle;
954 return _convert_image_util_error_code(__func__, err);
957 static char _JPEG_HEADER[] = { 0xFF, 0xD8 };
958 static char _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
959 static char _GIF_HEADER[] = { 'G', 'I', 'F' };
960 static char _BMP_HEADER[] = { 'B', 'M' };
962 static int _image_util_decode_create_image_handle(image_util_decode_h handle, const unsigned char *src_buffer)
964 image_util_type_e image_type = -1;
968 image_util_type_e image_type;
971 _JPEG_HEADER, sizeof(_JPEG_HEADER), IMAGE_UTIL_JPEG}
973 _PNG_HEADER, sizeof(_PNG_HEADER), IMAGE_UTIL_PNG}
975 _GIF_HEADER, sizeof(_GIF_HEADER), IMAGE_UTIL_GIF}
977 _BMP_HEADER, sizeof(_BMP_HEADER), IMAGE_UTIL_BMP}
980 int err = MM_UTIL_ERROR_NONE;
981 decode_encode_s *_handle = (decode_encode_s *) handle;
983 if (_handle == NULL || _handle->is_decode == FALSE) {
984 image_util_error("Invalid Handle");
985 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
987 if (src_buffer == NULL) {
988 image_util_error("Invalid input buffer");
989 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
992 for (i = 0; i < sizeof(image_header) / sizeof(image_header[0]); i++) {
993 if (strncmp((const char *)src_buffer, image_header[i].header, image_header[i].size) == 0) {
994 image_type = image_header[i].image_type;
999 _handle->image_type = image_type;
1001 switch (image_type) {
1002 case IMAGE_UTIL_JPEG:
1003 err = _image_util_decode_create_jpeg_handle(_handle);
1005 case IMAGE_UTIL_PNG:
1006 err = _image_util_decode_create_png_handle(_handle);
1008 case IMAGE_UTIL_GIF:
1009 err = _image_util_decode_create_gif_handle(_handle);
1011 case IMAGE_UTIL_BMP:
1012 err = _image_util_decode_create_bmp_handle(_handle);
1015 err = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1019 if (err != MM_UTIL_ERROR_NONE) {
1020 image_util_error("Error - create image handle");
1021 IMAGE_UTIL_SAFE_FREE(_handle);
1022 return _convert_image_util_error_code(__func__, err);
1025 return _convert_image_util_error_code(__func__, err);
1028 int image_util_decode_set_input_path(image_util_decode_h handle, const char *path)
1030 int err = IMAGE_UTIL_ERROR_NONE;
1031 decode_encode_s *_handle = (decode_encode_s *) handle;
1033 unsigned char *src_buffer = NULL;
1035 if (_handle == NULL || _handle->is_decode == FALSE) {
1036 image_util_error("Invalid Handle");
1037 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1039 image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
1041 if (_handle->src_buffer)
1042 _handle->src_buffer = NULL;
1044 fp = fopen(path, "r");
1046 image_util_error("File open failed");
1047 return IMAGE_UTIL_ERROR_NO_SUCH_FILE;
1049 src_buffer = (void *)malloc(sizeof(_PNG_HEADER));
1050 if (!fread(src_buffer, 1, sizeof(_PNG_HEADER), fp)) {
1051 image_util_error("File read failed");
1055 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
1058 err = _image_util_decode_create_image_handle(_handle, src_buffer);
1064 _handle->path = path;
1069 int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigned char *src_buffer, unsigned long long src_size)
1071 int err = IMAGE_UTIL_ERROR_NONE;
1072 decode_encode_s *_handle = (decode_encode_s *) handle;
1074 if (_handle == NULL || _handle->is_decode == FALSE) {
1075 image_util_error("Invalid Handle");
1076 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1078 if (src_buffer == NULL || src_size == 0) {
1079 image_util_error("Invalid input buffer");
1080 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1084 _handle->path = NULL;
1086 err = _image_util_decode_create_image_handle(_handle, src_buffer);
1088 _handle->src_buffer = (void *)src_buffer;
1089 _handle->src_size = src_size;
1094 int image_util_decode_set_output_buffer(image_util_decode_h handle, unsigned char **dst_buffer)
1096 int err = IMAGE_UTIL_ERROR_NONE;
1097 decode_encode_s *_handle = (decode_encode_s *) handle;
1099 if (_handle == NULL || _handle->is_decode == FALSE) {
1100 image_util_error("Invalid Handle");
1101 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1103 if (dst_buffer == NULL) {
1104 image_util_error("Invalid output buffer");
1105 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1108 _handle->dst_buffer = (void **)dst_buffer;
1113 int image_util_decode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace)
1115 int err = IMAGE_UTIL_ERROR_NONE;
1116 decode_encode_s *_handle = (decode_encode_s *) handle;
1118 if (_handle == NULL || _handle->is_decode == FALSE) {
1119 image_util_error("Invalid Handle");
1120 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1123 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
1124 switch (_handle->image_type) {
1125 case IMAGE_UTIL_JPEG:
1126 image_util_retvm_if((_convert_jpeg_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1128 case IMAGE_UTIL_PNG:
1129 image_util_retvm_if((_convert_png_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1131 case IMAGE_UTIL_GIF:
1132 image_util_retvm_if((_convert_gif_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1134 case IMAGE_UTIL_BMP:
1135 image_util_retvm_if((_convert_bmp_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1138 image_util_error("Invalid image type");
1139 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1142 _handle->colorspace = colorspace;
1147 int image_util_decode_set_jpeg_downscale(image_util_encode_h handle, image_util_scale_e down_scale)
1149 int err = IMAGE_UTIL_ERROR_NONE;
1150 decode_encode_s *_handle = (decode_encode_s *) handle;
1152 if (_handle == NULL || _handle->is_decode == FALSE) {
1153 image_util_error("Invalid Handle");
1154 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1156 if (_handle->image_type != IMAGE_UTIL_JPEG) {
1157 image_util_error("Wrong image format");
1158 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1160 image_util_retvm_if((down_scale < 0 || down_scale >= sizeof(image_util_scale_e)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downscale is invalid");
1162 _handle->down_scale = down_scale;
1167 static int _image_util_decode_internal(decode_encode_s * _handle)
1169 int err = MM_UTIL_ERROR_NONE;
1171 switch (_handle->image_type) {
1172 case IMAGE_UTIL_JPEG:
1174 mm_util_jpeg_yuv_data *jpeg_data;
1176 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1177 if (jpeg_data == NULL) {
1178 image_util_error("Invalid jpeg data");
1179 return MM_UTIL_ERROR_INVALID_PARAMETER;
1182 if (_handle->path) {
1183 if (_handle->down_scale < sizeof(image_util_scale_e))
1184 err = mm_util_decode_from_jpeg_file_with_downscale(jpeg_data, _handle->path, _convert_jpeg_colorspace_tbl[_handle->colorspace], _convert_decode_scale_tbl[_handle->down_scale]);
1186 err = mm_util_decode_from_jpeg_file(jpeg_data, _handle->path, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
1188 if (_handle->down_scale < sizeof(image_util_scale_e))
1189 err = mm_util_decode_from_jpeg_memory_with_downscale(jpeg_data, _handle->src_buffer, _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace], _convert_decode_scale_tbl[_handle->down_scale]);
1191 err = mm_util_decode_from_jpeg_memory(jpeg_data, _handle->src_buffer, _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
1194 if (err == MM_UTIL_ERROR_NONE) {
1195 *(_handle->dst_buffer) = jpeg_data->data;
1196 _handle->dst_size = (unsigned long long)jpeg_data->size;
1197 _handle->width = jpeg_data->width;
1198 _handle->height = jpeg_data->height;
1202 case IMAGE_UTIL_PNG:
1204 mm_util_png_data *png_data;
1206 png_data = (mm_util_png_data *) _handle->image_h;
1207 if (png_data == NULL) {
1208 image_util_error("Invalid png data");
1209 return MM_UTIL_ERROR_INVALID_PARAMETER;
1213 err = mm_util_decode_from_png_file(png_data, _handle->path);
1215 err = mm_util_decode_from_png_memory(png_data, &_handle->src_buffer, _handle->src_size);
1217 if (err == MM_UTIL_ERROR_NONE) {
1218 *(_handle->dst_buffer) = png_data->data;
1219 _handle->dst_size = png_data->size;
1220 _handle->width = png_data->width;
1221 _handle->height = png_data->height;
1225 case IMAGE_UTIL_GIF:
1227 mm_util_gif_data *gif_data;
1229 gif_data = (mm_util_gif_data *) _handle->image_h;
1230 if (gif_data == NULL) {
1231 image_util_error("Invalid gif data");
1232 return MM_UTIL_ERROR_INVALID_PARAMETER;
1236 err = mm_util_decode_from_gif_file(gif_data, _handle->path);
1238 err = mm_util_decode_from_gif_memory(gif_data, &_handle->src_buffer);
1240 if (err == MM_UTIL_ERROR_NONE) {
1241 *(_handle->dst_buffer) = gif_data->frames[0].data;
1242 _handle->dst_size = gif_data->size;
1243 _handle->width = gif_data->width;
1244 _handle->height = gif_data->height;
1248 case IMAGE_UTIL_BMP:
1250 mm_util_bmp_data *bmp_data;
1252 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1253 if (bmp_data == NULL) {
1254 image_util_error("Invalid bmp data");
1255 return MM_UTIL_ERROR_INVALID_PARAMETER;
1259 err = mm_util_decode_from_bmp_file(bmp_data, _handle->path);
1261 err = mm_util_decode_from_bmp_memory(bmp_data, &_handle->src_buffer, _handle->src_size);
1263 if (err == MM_UTIL_ERROR_NONE) {
1264 *(_handle->dst_buffer) = bmp_data->data;
1265 _handle->dst_size = bmp_data->size;
1266 _handle->width = bmp_data->width;
1267 _handle->height = bmp_data->height;
1272 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1279 int image_util_decode_run(image_util_decode_h handle, unsigned long *width, unsigned long *height, unsigned long long *size)
1281 int err = MM_UTIL_ERROR_NONE;
1282 decode_encode_s *_handle = (decode_encode_s *) handle;
1284 if (_handle == NULL || _handle->is_decode == FALSE) {
1285 image_util_error("Invalid Handle");
1286 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1288 if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
1289 image_util_error("Invalid input/output");
1290 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1293 err = _image_util_decode_internal(_handle);
1295 if (err != MM_UTIL_ERROR_NONE) {
1296 image_util_error("Error - decode run");
1297 return _convert_image_util_error_code(__func__, err);
1301 *width = _handle->width;
1303 *height = _handle->height;
1305 *size = _handle->dst_size;
1307 return _convert_image_util_error_code(__func__, err);
1310 gpointer _image_util_decode_thread(gpointer data)
1312 decode_encode_s *_handle = (decode_encode_s *) data;
1313 int err = MM_UTIL_ERROR_NONE;
1314 gint64 end_time = 0;
1317 image_util_error("[ERROR] - handle");
1321 while (!_handle->is_finish) {
1322 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1323 image_util_debug("waiting...");
1324 g_mutex_lock(&(_handle->thread_mutex));
1325 g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
1326 image_util_debug("<=== get run decode thread signal");
1327 g_mutex_unlock(&(_handle->thread_mutex));
1329 if (_handle->is_finish) {
1330 image_util_debug("exit loop");
1334 err = _image_util_decode_internal(_handle);
1335 if (err == MM_UTIL_ERROR_NONE)
1336 image_util_debug("Success - decode_internal");
1338 image_util_error("Error - decode_internal");
1340 if (_handle->_decode_cb) {
1341 image_util_debug("completed_cb");
1342 _handle->is_finish = TRUE;
1343 _handle->_decode_cb->image_decode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_decode_cb->user_data, _handle->width, _handle->height, _handle->dst_size);
1347 image_util_debug("exit thread");
1352 static int _image_util_decode_create_thread(decode_encode_s * handle)
1354 int err = MM_UTIL_ERROR_NONE;
1356 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1358 g_mutex_init(&(handle->thread_mutex));
1360 g_cond_init(&(handle->thread_cond));
1363 handle->thread = g_thread_new("decode_thread", (GThreadFunc) _image_util_decode_thread, (gpointer) handle);
1364 if (!handle->thread) {
1365 image_util_error("ERROR - create thread");
1366 g_mutex_clear(&(handle->thread_mutex));
1368 g_cond_clear(&(handle->thread_cond));
1369 return MM_UTIL_ERROR_INVALID_OPERATION;
1375 int image_util_decode_run_async(image_util_decode_h handle, image_util_decode_completed_cb completed_cb, void *user_data)
1377 int err = MM_UTIL_ERROR_NONE;
1378 decode_encode_s *_handle = (decode_encode_s *) handle;
1380 if (_handle == NULL || _handle->is_decode == FALSE) {
1381 image_util_error("Invalid Handle");
1382 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1384 if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
1385 image_util_error("Invalid input/output");
1386 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1388 image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
1390 if (_handle->_decode_cb != NULL) {
1391 IMAGE_UTIL_SAFE_FREE(_handle->_decode_cb);
1392 _handle->_decode_cb = NULL;
1394 _handle->_decode_cb = (decode_cb_s *) calloc(1, sizeof(decode_cb_s));
1395 image_util_retvm_if((_handle->_decode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
1397 _handle->_decode_cb->user_data = user_data;
1398 _handle->_decode_cb->image_decode_completed_cb = completed_cb;
1400 err = _image_util_decode_create_thread(_handle);
1402 return _convert_image_util_error_code(__func__, err);
1405 int image_util_decode_destroy(image_util_decode_h handle)
1407 int err = IMAGE_UTIL_ERROR_NONE;
1408 decode_encode_s *_handle = (decode_encode_s *) handle;
1410 image_util_debug("image_util_encode_png_destroy");
1412 if (_handle == NULL || _handle->is_decode == FALSE) {
1413 image_util_error("Invalid Handle");
1414 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1417 switch (_handle->image_type) {
1418 case IMAGE_UTIL_JPEG:
1420 mm_util_jpeg_yuv_data *jpeg_data;
1422 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1423 if (jpeg_data == NULL) {
1424 image_util_error("Invalid jpeg data");
1425 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1427 IMAGE_UTIL_SAFE_FREE(jpeg_data);
1430 case IMAGE_UTIL_PNG:
1432 mm_util_png_data *png_data;
1434 png_data = (mm_util_png_data *) _handle->image_h;
1435 if (png_data == NULL) {
1436 image_util_error("Invalid png data");
1437 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1439 IMAGE_UTIL_SAFE_FREE(png_data);
1442 case IMAGE_UTIL_GIF:
1444 mm_util_gif_data *gif_data;
1446 gif_data = (mm_util_gif_data *) _handle->image_h;
1447 if (gif_data == NULL) {
1448 image_util_error("Invalid gif data");
1449 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1451 IMAGE_UTIL_SAFE_FREE(gif_data);
1454 case IMAGE_UTIL_BMP:
1456 mm_util_bmp_data *bmp_data;
1458 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1459 if (bmp_data == NULL) {
1460 image_util_error("Invalid bmp data");
1461 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1463 IMAGE_UTIL_SAFE_FREE(bmp_data);
1470 /* g_thread_exit(handle->thread); */
1471 if (_handle->thread) {
1472 _handle->is_finish = TRUE;
1473 g_mutex_lock(&(_handle->thread_mutex));
1474 g_cond_signal(&(_handle->thread_cond));
1475 image_util_debug("===> send signal(finish) to decode_thread");
1476 g_mutex_unlock(&(_handle->thread_mutex));
1478 g_thread_join(_handle->thread);
1480 g_mutex_clear(&(_handle->thread_mutex));
1482 g_cond_clear(&(_handle->thread_cond));
1485 IMAGE_UTIL_SAFE_FREE(_handle);
1490 static int _image_util_encode_create_jpeg_handle(decode_encode_s * handle)
1492 int err = MM_UTIL_ERROR_NONE;
1494 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1496 mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data));
1497 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1499 handle->image_h = (MMHandleType) _handle;
1500 handle->colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888;
1501 handle->quality = 20;
1506 static int _image_util_encode_create_png_handle(decode_encode_s * handle)
1508 int err = MM_UTIL_ERROR_NONE;
1510 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1512 mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data));
1513 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1515 mm_util_init_encode_png(_handle);
1517 handle->image_h = (MMHandleType) _handle;
1522 static int _image_util_encode_create_gif_handle(decode_encode_s * handle)
1524 int err = MM_UTIL_ERROR_NONE;
1526 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1528 mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data));
1529 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1531 _handle->frames = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data));
1532 if (_handle->frames == NULL) {
1533 image_util_error("Error - OUT_OF_MEMORY");
1534 IMAGE_UTIL_SAFE_FREE(_handle);
1535 return MM_UTIL_ERROR_OUT_OF_MEMORY;
1538 mm_util_gif_encode_set_image_count(_handle, 1);
1539 handle->image_h = (MMHandleType) _handle;
1544 static int _image_util_encode_create_bmp_handle(decode_encode_s * handle)
1546 int err = MM_UTIL_ERROR_NONE;
1548 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1550 mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data));
1551 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1553 handle->image_h = (MMHandleType) _handle;
1558 int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * handle)
1560 int err = MM_UTIL_ERROR_NONE;
1562 image_util_debug("image_util_encode_create");
1564 image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1566 decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
1567 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
1569 _handle->image_type = image_type;
1570 _handle->src_buffer = NULL;
1571 _handle->dst_buffer = NULL;
1572 _handle->path = NULL;
1573 _handle->image_h = 0;
1574 _handle->is_decode = FALSE;
1576 switch (image_type) {
1577 case IMAGE_UTIL_JPEG:
1578 err = _image_util_encode_create_jpeg_handle(_handle);
1580 case IMAGE_UTIL_PNG:
1581 err = _image_util_encode_create_png_handle(_handle);
1583 case IMAGE_UTIL_GIF:
1584 err = _image_util_encode_create_gif_handle(_handle);
1586 case IMAGE_UTIL_BMP:
1587 err = _image_util_encode_create_bmp_handle(_handle);
1590 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1594 if (err != MM_UTIL_ERROR_NONE) {
1595 image_util_error("Error - create image handle");
1596 IMAGE_UTIL_SAFE_FREE(_handle);
1597 return _convert_image_util_error_code(__func__, err);
1600 *handle = (image_util_encode_h) _handle;
1602 return _convert_image_util_error_code(__func__, err);
1605 int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long width, unsigned long height)
1607 int err = IMAGE_UTIL_ERROR_NONE;
1608 decode_encode_s *_handle = (decode_encode_s *) handle;
1610 if (_handle == NULL || _handle->is_decode == TRUE) {
1611 image_util_error("Invalid Handle");
1612 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1614 image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
1616 switch (_handle->image_type) {
1617 case IMAGE_UTIL_JPEG:
1619 mm_util_jpeg_yuv_data *jpeg_data;
1621 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1622 if (jpeg_data == NULL) {
1623 image_util_error("Invalid jpeg data");
1624 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1626 jpeg_data->width = width;
1627 jpeg_data->height = height;
1630 case IMAGE_UTIL_PNG:
1632 mm_util_png_data *png_data;
1634 png_data = (mm_util_png_data *) _handle->image_h;
1635 if (png_data == NULL) {
1636 image_util_error("Invalid png data");
1637 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1639 mm_util_png_encode_set_width(png_data, width);
1640 mm_util_png_encode_set_height(png_data, height);
1643 case IMAGE_UTIL_GIF:
1645 mm_util_gif_data *gif_data;
1647 gif_data = (mm_util_gif_data *) _handle->image_h;
1648 if (gif_data == NULL) {
1649 image_util_error("Invalid gif data");
1650 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1652 mm_util_gif_encode_set_width(gif_data, width);
1653 mm_util_gif_encode_set_height(gif_data, height);
1656 case IMAGE_UTIL_BMP:
1658 mm_util_bmp_data *bmp_data;
1660 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1661 if (bmp_data == NULL) {
1662 image_util_error("Invalid bmp data");
1663 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1665 mm_util_bmp_encode_set_width(bmp_data, width);
1666 mm_util_bmp_encode_set_height(bmp_data, height);
1670 err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1674 _handle->width = width;
1675 _handle->height = height;
1680 int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace)
1682 int err = IMAGE_UTIL_ERROR_NONE;
1683 decode_encode_s *_handle = (decode_encode_s *) handle;
1685 if (_handle == NULL || _handle->is_decode == TRUE) {
1686 image_util_error("Invalid Handle");
1687 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1690 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
1691 switch (_handle->image_type) {
1692 case IMAGE_UTIL_JPEG:
1693 image_util_retvm_if((_convert_jpeg_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1695 case IMAGE_UTIL_PNG:
1696 image_util_retvm_if((_convert_png_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1698 case IMAGE_UTIL_GIF:
1699 image_util_retvm_if((_convert_gif_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1701 case IMAGE_UTIL_BMP:
1702 image_util_retvm_if((_convert_bmp_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1705 image_util_error("Invalid image type");
1706 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1709 _handle->colorspace = colorspace;
1714 int image_util_encode_set_jpeg_quality(image_util_encode_h handle, int quality)
1716 int err = IMAGE_UTIL_ERROR_NONE;
1717 decode_encode_s *_handle = (decode_encode_s *) handle;
1719 if (_handle == NULL || _handle->is_decode == TRUE) {
1720 image_util_error("Invalid Handle");
1721 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1723 if (_handle->image_type != IMAGE_UTIL_JPEG) {
1724 image_util_error("Wrong image format");
1725 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1727 image_util_retvm_if((quality <= 0 || quality > 100), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid quality");
1729 _handle->quality = quality;
1734 int image_util_encode_set_png_compression(image_util_encode_h handle, image_util_png_compression_e compression)
1736 int err = IMAGE_UTIL_ERROR_NONE;
1737 decode_encode_s *_handle = (decode_encode_s *) handle;
1738 mm_util_png_data *png_data;
1740 if (_handle == NULL || _handle->is_decode == TRUE) {
1741 image_util_error("Invalid Handle");
1742 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1744 if (_handle->image_type != IMAGE_UTIL_PNG) {
1745 image_util_error("Wrong image format");
1746 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1748 image_util_retvm_if((compression < IMAGE_UTIL_PNG_COMPRESSION_0 || compression > IMAGE_UTIL_PNG_COMPRESSION_9), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid compression value");
1750 png_data = (mm_util_png_data *) _handle->image_h;
1751 if (png_data == NULL) {
1752 image_util_error("Invalid png data");
1753 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1756 mm_util_png_encode_set_compression_level(png_data, compression);
1761 int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigned char *src_buffer)
1763 int err = IMAGE_UTIL_ERROR_NONE;
1764 decode_encode_s *_handle = (decode_encode_s *) handle;
1766 if (_handle == NULL || _handle->is_decode == TRUE) {
1767 image_util_error("Invalid Handle");
1768 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1770 if (src_buffer == NULL) {
1771 image_util_error("Invalid input buffer");
1772 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1775 _handle->src_buffer = (void *)src_buffer;
1780 int image_util_encode_set_output_path(image_util_encode_h handle, const char *path)
1782 int err = IMAGE_UTIL_ERROR_NONE;
1783 decode_encode_s *_handle = (decode_encode_s *) handle;
1785 if (_handle == NULL || _handle->is_decode == TRUE) {
1786 image_util_error("Invalid Handle");
1787 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1789 image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
1791 if (_handle->dst_buffer)
1792 _handle->dst_buffer = NULL;
1794 _handle->path = path;
1799 int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned char **dst_buffer)
1801 int err = IMAGE_UTIL_ERROR_NONE;
1802 decode_encode_s *_handle = (decode_encode_s *) handle;
1804 if (_handle == NULL || _handle->is_decode == TRUE) {
1805 image_util_error("Invalid Handle");
1806 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1808 if (_handle->image_type == IMAGE_UTIL_BMP) {
1809 image_util_error("BMP library does not support encoding to memory");
1810 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1812 if (dst_buffer == NULL) {
1813 image_util_error("Invalid output buffer");
1814 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1818 _handle->path = NULL;
1820 _handle->dst_buffer = (void **)dst_buffer;
1825 static int _image_util_encode_internal(decode_encode_s * _handle)
1827 int err = MM_UTIL_ERROR_NONE;
1829 switch (_handle->image_type) {
1830 case IMAGE_UTIL_JPEG:
1833 err = mm_util_jpeg_encode_to_file(_handle->path, _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
1835 err = mm_util_jpeg_encode_to_memory(_handle->dst_buffer, (int *)&(_handle->dst_size), _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
1838 case IMAGE_UTIL_PNG:
1840 mm_util_png_data *png_data;
1842 png_data = (mm_util_png_data *) _handle->image_h;
1843 if (png_data == NULL) {
1844 image_util_error("Invalid png data");
1845 return MM_UTIL_ERROR_INVALID_PARAMETER;
1849 err = mm_util_encode_to_png_file(&(_handle->src_buffer), png_data, _handle->path);
1851 err = mm_util_encode_to_png_memory(&(_handle->src_buffer), png_data);
1853 if (err == MM_UTIL_ERROR_NONE) {
1854 if (_handle->dst_buffer)
1855 *(_handle->dst_buffer) = png_data->data;
1856 _handle->dst_size = png_data->size;
1857 _handle->width = png_data->width;
1858 _handle->height = png_data->height;
1862 case IMAGE_UTIL_GIF:
1864 mm_util_gif_data *gif_data;
1865 void *dst_buffer = NULL;
1867 gif_data = (mm_util_gif_data *) _handle->image_h;
1868 if (gif_data == NULL || gif_data->frames == NULL) {
1869 image_util_error("Invalid gif data");
1870 return MM_UTIL_ERROR_INVALID_PARAMETER;
1873 gif_data->frames[0].data = _handle->src_buffer;
1875 err = mm_util_encode_gif_to_file(gif_data, _handle->path);
1877 err = mm_util_encode_gif_to_memory(gif_data, &dst_buffer);
1879 if (err == MM_UTIL_ERROR_NONE) {
1880 if (_handle->dst_buffer)
1881 *(_handle->dst_buffer) = (unsigned char *)dst_buffer;
1882 _handle->dst_size = gif_data->size;
1883 _handle->width = gif_data->width;
1884 _handle->height = gif_data->height;
1888 case IMAGE_UTIL_BMP:
1890 mm_util_bmp_data *bmp_data;
1892 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1893 if (bmp_data == NULL) {
1894 image_util_error("Invalid bmp data");
1895 return MM_UTIL_ERROR_INVALID_PARAMETER;
1898 bmp_data->data = _handle->src_buffer;
1900 err = mm_util_encode_bmp_to_file(bmp_data, _handle->path);
1902 image_util_error("Not yet implemented");
1903 return MM_UTIL_ERROR_INVALID_PARAMETER;
1906 if (err == MM_UTIL_ERROR_NONE) {
1907 if (_handle->dst_buffer)
1908 *(_handle->dst_buffer) = bmp_data->data;
1909 _handle->dst_size = bmp_data->size;
1910 _handle->width = bmp_data->width;
1911 _handle->height = bmp_data->height;
1916 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1923 int image_util_encode_run(image_util_encode_h handle, unsigned long long *size)
1925 int err = MM_UTIL_ERROR_NONE;
1926 decode_encode_s *_handle = (decode_encode_s *) handle;
1928 if (_handle == NULL || _handle->is_decode == TRUE) {
1929 image_util_error("Invalid Handle");
1930 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1932 if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
1933 image_util_error("Invalid input/output");
1934 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1936 image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
1938 err = _image_util_encode_internal(_handle);
1940 if (err != MM_UTIL_ERROR_NONE) {
1941 image_util_error("Error - encode run");
1942 return _convert_image_util_error_code(__func__, err);
1946 *size = _handle->dst_size;
1948 return _convert_image_util_error_code(__func__, err);
1951 gpointer _image_util_encode_thread(gpointer data)
1953 decode_encode_s *_handle = (decode_encode_s *) data;
1954 int err = MM_UTIL_ERROR_NONE;
1955 gint64 end_time = 0;
1958 image_util_error("[ERROR] - handle");
1962 while (!_handle->is_finish) {
1963 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1964 image_util_debug("waiting...");
1965 g_mutex_lock(&(_handle->thread_mutex));
1966 g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
1967 image_util_debug("<=== get run encode thread signal");
1968 g_mutex_unlock(&(_handle->thread_mutex));
1970 if (_handle->is_finish) {
1971 image_util_debug("exit loop");
1975 err = _image_util_encode_internal(_handle);
1976 if (err == MM_UTIL_ERROR_NONE)
1977 image_util_debug("Success - encode_internal");
1979 image_util_error("Error - encode_internal");
1981 if (_handle->_encode_cb) {
1982 image_util_debug("completed_cb");
1983 _handle->is_finish = TRUE;
1984 _handle->_encode_cb->image_encode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_encode_cb->user_data, _handle->dst_size);
1988 image_util_debug("exit thread");
1993 static int _image_util_encode_create_thread(decode_encode_s * handle)
1995 int ret = MM_UTIL_ERROR_NONE;
1997 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1999 g_mutex_init(&(handle->thread_mutex));
2001 g_cond_init(&(handle->thread_cond));
2004 handle->thread = g_thread_new("encode_thread", (GThreadFunc) _image_util_encode_thread, (gpointer) handle);
2005 if (!handle->thread) {
2006 image_util_error("ERROR - create thread");
2007 g_mutex_clear(&(handle->thread_mutex));
2009 g_cond_clear(&(handle->thread_cond));
2010 return MM_UTIL_ERROR_INVALID_OPERATION;
2016 int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb completed_cb, void *user_data)
2018 int err = MM_UTIL_ERROR_NONE;
2019 decode_encode_s *_handle = (decode_encode_s *) handle;
2021 if (_handle == NULL || _handle->is_decode == TRUE) {
2022 image_util_error("Invalid Handle");
2023 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2025 if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
2026 image_util_error("Invalid input/output");
2027 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2029 image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
2031 image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
2033 if (_handle->_encode_cb != NULL) {
2034 IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb);
2035 _handle->_encode_cb = NULL;
2037 _handle->_encode_cb = (encode_cb_s *) calloc(1, sizeof(encode_cb_s));
2038 image_util_retvm_if((_handle->_encode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
2040 _handle->_encode_cb->user_data = user_data;
2041 _handle->_encode_cb->image_encode_completed_cb = completed_cb;
2043 err = _image_util_encode_create_thread(_handle);
2045 return _convert_image_util_error_code(__func__, err);
2048 int image_util_encode_destroy(image_util_encode_h handle)
2050 int err = IMAGE_UTIL_ERROR_NONE;
2051 decode_encode_s *_handle = (decode_encode_s *) handle;
2053 image_util_debug("image_util_encode_destroy");
2055 if (_handle == NULL || _handle->is_decode == TRUE) {
2056 image_util_error("Invalid Handle");
2057 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2060 switch (_handle->image_type) {
2061 case IMAGE_UTIL_JPEG:
2063 mm_util_jpeg_yuv_data *jpeg_data;
2065 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
2066 if (jpeg_data == NULL) {
2067 image_util_error("Invalid jpeg data");
2068 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2070 IMAGE_UTIL_SAFE_FREE(jpeg_data);
2073 case IMAGE_UTIL_PNG:
2075 mm_util_png_data *png_data;
2077 png_data = (mm_util_png_data *) _handle->image_h;
2078 if (png_data == NULL) {
2079 image_util_error("Invalid png data");
2080 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2082 IMAGE_UTIL_SAFE_FREE(png_data);
2085 case IMAGE_UTIL_GIF:
2087 mm_util_gif_data *gif_data;
2089 gif_data = (mm_util_gif_data *) _handle->image_h;
2090 if (gif_data == NULL) {
2091 image_util_error("Invalid gif data");
2092 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2094 IMAGE_UTIL_SAFE_FREE(gif_data->frames);
2095 IMAGE_UTIL_SAFE_FREE(gif_data);
2098 case IMAGE_UTIL_BMP:
2100 mm_util_bmp_data *bmp_data;
2102 bmp_data = (mm_util_bmp_data *) _handle->image_h;
2103 if (bmp_data == NULL) {
2104 image_util_error("Invalid bmp data");
2105 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2107 IMAGE_UTIL_SAFE_FREE(bmp_data);
2111 err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2115 /* g_thread_exit(handle->thread); */
2116 if (_handle->thread) {
2117 _handle->is_finish = TRUE;
2118 g_mutex_lock(&(_handle->thread_mutex));
2119 g_cond_signal(&(_handle->thread_cond));
2120 image_util_debug("===> send signal(finish) to decode_thread");
2121 g_mutex_unlock(&(_handle->thread_mutex));
2123 g_thread_join(_handle->thread);
2125 g_mutex_clear(&(_handle->thread_mutex));
2127 g_cond_clear(&(_handle->thread_cond));
2130 IMAGE_UTIL_SAFE_FREE(_handle);