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; } }
36 static int _convert_colorspace_tbl[] = {
37 MM_UTIL_IMG_FMT_YUV420, /* IMAGE_UTIL_COLORSPACE_YUV420 */
38 MM_UTIL_IMG_FMT_YUV422, /* IMAGE_UTIL_COLORSPACE_YUV422 */
39 MM_UTIL_IMG_FMT_I420, /* IMAGE_UTIL_COLORSPACE_I420 */
40 MM_UTIL_IMG_FMT_NV12, /* IMAGE_UTIL_COLORSPACE_NV12 */
41 MM_UTIL_IMG_FMT_UYVY, /* IMAGE_UTIL_COLORSPACE_UYVY */
42 MM_UTIL_IMG_FMT_YUYV, /* IMAGE_UTIL_COLORSPACE_YUYV */
43 MM_UTIL_IMG_FMT_RGB565, /* IMAGE_UTIL_COLORSPACE_RGB565 */
44 MM_UTIL_IMG_FMT_RGB888, /* IMAGE_UTIL_COLORSPACE_RGB888 */
45 MM_UTIL_IMG_FMT_ARGB8888, /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
46 MM_UTIL_IMG_FMT_BGRA8888, /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
47 MM_UTIL_IMG_FMT_RGBA8888, /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
48 MM_UTIL_IMG_FMT_BGRX8888, /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
49 MM_UTIL_JPEG_FMT_NV21, /* IMAGE_UTIL_COLORSPACE_NV12 */
50 MM_UTIL_JPEG_FMT_NV16, /* IMAGE_UTIL_COLORSPACE_NV16 */
51 MM_UTIL_JPEG_FMT_NV61, /* IMAGE_UTIL_COLORSPACE_NV61 */
54 static int _convert_encode_colorspace_tbl[] = {
55 MM_UTIL_JPEG_FMT_YUV420 , /* IMAGE_UTIL_COLORSPACE_YUV420 */
56 -1 , /* IMAGE_UTIL_COLORSPACE_YUV422 */
57 MM_UTIL_JPEG_FMT_YUV420 , /* IMAGE_UTIL_COLORSPACE_I420 */
58 MM_UTIL_JPEG_FMT_NV12 , /* IMAGE_UTIL_COLORSPACE_NV12 */
59 -1 , /* IMAGE_UTIL_COLORSPACE_UYVY */
60 -1 , /* IMAGE_UTIL_COLORSPACE_YUYV */
61 -1 , /* IMAGE_UTIL_COLORSPACE_RGB565 */
62 MM_UTIL_JPEG_FMT_RGB888 , /* IMAGE_UTIL_COLORSPACE_RGB888 */
63 MM_UTIL_JPEG_FMT_ARGB8888 , /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
64 MM_UTIL_JPEG_FMT_BGRA8888 , /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
65 MM_UTIL_JPEG_FMT_RGBA8888 , /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
66 -1 , /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
67 -1 , /* IMAGE_UTIL_COLORSPACE_NV21 */
68 -1 , /* IMAGE_UTIL_COLORSPACE_NV16 */
69 -1 , /* IMAGE_UTIL_COLORSPACE_NV61 */
72 static int _convert_jpeg_colorspace_tbl[] = {
73 MM_UTIL_JPEG_FMT_YUV420 , /* IMAGE_UTIL_COLORSPACE_YUV420 */
74 -1 , /* IMAGE_UTIL_COLORSPACE_YUV422 */
75 MM_UTIL_JPEG_FMT_YUV420 , /* IMAGE_UTIL_COLORSPACE_I420 */
76 MM_UTIL_JPEG_FMT_NV12 , /* IMAGE_UTIL_COLORSPACE_NV12 */
77 -1 , /* IMAGE_UTIL_COLORSPACE_UYVY */
78 -1 , /* IMAGE_UTIL_COLORSPACE_YUYV */
79 -1 , /* IMAGE_UTIL_COLORSPACE_RGB565 */
80 MM_UTIL_JPEG_FMT_RGB888 , /* IMAGE_UTIL_COLORSPACE_RGB888 */
81 MM_UTIL_JPEG_FMT_ARGB8888 , /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
82 MM_UTIL_JPEG_FMT_BGRA8888 , /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
83 MM_UTIL_JPEG_FMT_RGBA8888 , /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
84 -1 , /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
85 -1 , /* IMAGE_UTIL_COLORSPACE_NV21 */
86 -1 , /* IMAGE_UTIL_COLORSPACE_NV16 */
87 -1 , /* IMAGE_UTIL_COLORSPACE_NV61 */
90 static int _convert_png_colorspace_tbl[] = {
91 -1 , /* IMAGE_UTIL_COLORSPACE_YUV420 */
92 -1 , /* IMAGE_UTIL_COLORSPACE_YUV422 */
93 -1 , /* IMAGE_UTIL_COLORSPACE_I420 */
94 -1 , /* IMAGE_UTIL_COLORSPACE_NV12 */
95 -1 , /* IMAGE_UTIL_COLORSPACE_UYVY */
96 -1 , /* IMAGE_UTIL_COLORSPACE_YUYV */
97 -1 , /* IMAGE_UTIL_COLORSPACE_RGB565 */
98 -1 , /* IMAGE_UTIL_COLORSPACE_RGB888 */
99 -1 , /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
100 -1 , /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
101 MM_UTIL_PNG_COLOR_TYPE_RGB_ALPHA , /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
102 -1 , /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
103 -1 , /* IMAGE_UTIL_COLORSPACE_NV21 */
104 -1 , /* IMAGE_UTIL_COLORSPACE_NV16 */
105 -1 , /* IMAGE_UTIL_COLORSPACE_NV61 */
108 static int _convert_gif_colorspace_tbl[] = {
109 -1 , /* IMAGE_UTIL_COLORSPACE_YUV420 */
110 -1 , /* IMAGE_UTIL_COLORSPACE_YUV422 */
111 -1 , /* IMAGE_UTIL_COLORSPACE_I420 */
112 -1 , /* IMAGE_UTIL_COLORSPACE_NV12 */
113 -1 , /* IMAGE_UTIL_COLORSPACE_UYVY */
114 -1 , /* IMAGE_UTIL_COLORSPACE_YUYV */
115 -1 , /* IMAGE_UTIL_COLORSPACE_RGB565 */
116 -1 , /* IMAGE_UTIL_COLORSPACE_RGB888 */
117 -1 , /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
118 -1 , /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
119 MM_UTIL_GIF_FMT_RGBA8888 , /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
120 -1 , /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
121 -1 , /* IMAGE_UTIL_COLORSPACE_NV21 */
122 -1 , /* IMAGE_UTIL_COLORSPACE_NV16 */
123 -1 , /* IMAGE_UTIL_COLORSPACE_NV61 */
126 static int _convert_bmp_colorspace_tbl[] = {
127 -1 , /* IMAGE_UTIL_COLORSPACE_YUV420 */
128 -1 , /* IMAGE_UTIL_COLORSPACE_YUV422 */
129 -1 , /* IMAGE_UTIL_COLORSPACE_I420 */
130 -1 , /* IMAGE_UTIL_COLORSPACE_NV12 */
131 -1 , /* IMAGE_UTIL_COLORSPACE_UYVY */
132 -1 , /* IMAGE_UTIL_COLORSPACE_YUYV */
133 -1 , /* IMAGE_UTIL_COLORSPACE_RGB565 */
134 -1 , /* IMAGE_UTIL_COLORSPACE_RGB888 */
135 -1 , /* IMAGE_UTIL_COLORSPACE_ARGB8888 */
136 -1 , /* IMAGE_UTIL_COLORSPACE_BGRA8888 */
137 MM_UTIL_BMP_FMT_RGBA8888 , /* IMAGE_UTIL_COLORSPACE_RGBA8888 */
138 -1 , /* IMAGE_UTIL_COLORSPACE_BGRX8888 */
139 -1 , /* IMAGE_UTIL_COLORSPACE_NV21 */
140 -1 , /* IMAGE_UTIL_COLORSPACE_NV16 */
141 -1 , /* IMAGE_UTIL_COLORSPACE_NV61 */
144 static int _convert_decode_scale_tbl[] = {
145 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_1,
146 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_2,
147 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_4,
148 MM_UTIL_JPEG_DECODE_DOWNSCALE_1_8,
151 static int _convert_image_util_error_code(const char *func, int code)
153 int ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
154 char *errorstr = NULL;
156 case MM_UTIL_ERROR_NONE:
157 ret = IMAGE_UTIL_ERROR_NONE;
158 errorstr = strdup("ERROR_NONE");
160 case MM_UTIL_ERROR_NO_SUCH_FILE:
161 ret = IMAGE_UTIL_ERROR_NO_SUCH_FILE;
162 errorstr = strdup("NO_SUCH_FILE");
164 case MM_UTIL_ERROR_INVALID_PARAMETER:
165 ret = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
166 errorstr = strdup("INVALID_PARAMETER");
168 case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
169 ret = IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
170 errorstr = strdup("NOT_SUPPORTED_FORMAT");
172 case MM_UTIL_ERROR_OUT_OF_MEMORY:
173 ret = IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
174 errorstr = strdup("OUT_OF_MEMORY");
176 case MM_UTIL_ERROR_INVALID_OPERATION:
178 ret = IMAGE_UTIL_ERROR_INVALID_OPERATION;
179 errorstr = strdup("INVALID_OPERATION");
183 image_util_debug("[%s] %s(0x%08x)", func, errorstr, ret);
184 IMAGE_UTIL_SAFE_FREE(errorstr);
188 static image_util_error_e _image_util_error_convert(int error)
191 case MM_UTIL_ERROR_NONE:
192 image_util_debug("Error None");
193 return IMAGE_UTIL_ERROR_NONE;
194 case MM_UTIL_ERROR_INVALID_PARAMETER:
195 image_util_error("INVALID_PARAMETER(0x%08x)", IMAGE_UTIL_ERROR_INVALID_PARAMETER);
196 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
197 case MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT:
198 image_util_error("NOT_SUPPORTED_FORMAT(0x%08x)", IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT);
199 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
200 case MM_UTIL_ERROR_OUT_OF_MEMORY:
201 image_util_error("OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
202 return IMAGE_UTIL_ERROR_OUT_OF_MEMORY;
204 case MM_UTIL_ERROR_INVALID_OPERATION:
206 image_util_error("INVALID_OPERATION(0x%08x)", error);
207 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
211 static void _image_util_transform_completed_cb(media_packet_h *dst, int error, void *user_data)
213 int error_value = IMAGE_UTIL_ERROR_NONE;
214 image_util_cb_s *_util_cb = (image_util_cb_s *)user_data;
216 if ((_util_cb != NULL) && (_util_cb->image_processing_completed_cb != NULL)) {
217 error_value = _image_util_error_convert(error);
218 _util_cb->image_processing_completed_cb(dst, error_value, _util_cb->user_data);
224 static int _image_util_create_transform_handle(transformation_s *handle)
226 int err = MM_UTIL_ERROR_NONE;
227 MMHandleType image_h;
229 err = mm_util_create(&image_h);
230 if (err != MM_UTIL_ERROR_NONE) {
231 image_util_error("Error - mm_util_create");
232 return _convert_image_util_error_code(__func__, err);
235 handle->image_h = image_h;
237 return _convert_image_util_error_code(__func__, err);
240 static bool _image_util_check_resolution(int width, int height)
243 image_util_error("invalid width [%d]", width);
248 image_util_error("invalid height [%d]", height);
255 int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void *user_data)
259 image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
261 /* RGB has higher precedence than YUV */
262 for (i = sizeof(_convert_encode_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
263 if (_convert_encode_colorspace_tbl[i] != -1)
264 if (false == callback(i, user_data))
265 return IMAGE_UTIL_ERROR_NONE;
269 return IMAGE_UTIL_ERROR_NONE;
272 int image_util_transform_create(transformation_h *handle)
274 int err = MM_UTIL_ERROR_NONE;
276 image_util_debug("image_util_create");
278 image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
280 transformation_s *_handle = (transformation_s *)calloc(1, sizeof(transformation_s));
281 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
283 _handle->colorspace = -1;
284 _handle->_util_cb = NULL;
285 _handle->image_h = 0;
286 _handle->hardware_acceleration = false;
287 _handle->set_convert = false;
288 _handle->set_resize = false;
289 _handle->set_rotate = false;
290 _handle->set_crop = false;
292 err = _image_util_create_transform_handle(_handle);
293 if (err != MM_UTIL_ERROR_NONE) {
294 image_util_error("Error - create transform handle");
295 IMAGE_UTIL_SAFE_FREE(_handle);
296 return _convert_image_util_error_code(__func__, err);
299 *handle = (transformation_h)_handle;
301 return _convert_image_util_error_code(__func__, err);
304 int image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
306 int err = MM_UTIL_ERROR_NONE;
307 transformation_s *_handle = (transformation_s *)handle;
309 image_util_debug("Set hardware_acceleration %d", mode);
311 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
312 #ifndef ENABLE_HW_ACCELERATION
313 image_util_retvm_if((mode == true), IMAGE_UTIL_ERROR_NOT_SUPPORTED, "hardware acceleration is not supported");
316 err = mm_util_set_hardware_acceleration(_handle->image_h, mode);
317 if (err != MM_UTIL_ERROR_NONE) {
318 image_util_error("Error - Set hardware_acceleration");
319 return _convert_image_util_error_code(__func__, err);
322 image_util_debug("Set hardware_acceleration %d", mode);
323 _handle->hardware_acceleration = mode;
325 return _convert_image_util_error_code(__func__, err);
328 int image_util_transform_set_colorspace(transformation_h handle, image_util_colorspace_e colorspace)
330 int err = MM_UTIL_ERROR_NONE;
331 transformation_s *_handle = (transformation_s *)handle;
333 image_util_debug("Set colorspace_convert_info [%d]", colorspace);
335 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
337 err = mm_util_set_colorspace_convert(_handle->image_h, colorspace);
338 if (err != MM_UTIL_ERROR_NONE) {
339 image_util_error("Error - Set colorspace convert");
340 return _convert_image_util_error_code(__func__, err);
343 _handle->colorspace = colorspace;
344 _handle->set_convert = true;
346 return _convert_image_util_error_code(__func__, err);
349 int image_util_transform_set_resolution(transformation_h handle, unsigned int width, unsigned int height)
351 int err = MM_UTIL_ERROR_NONE;
352 transformation_s *_handle = (transformation_s *)handle;
354 image_util_debug("Set resize_info w[%d] h[%d]", width, height);
356 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
357 image_util_retvm_if((_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
358 image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
360 err = mm_util_set_resolution(_handle->image_h, width, height);
361 if (err != MM_UTIL_ERROR_NONE) {
362 image_util_error("Error - Set resolution");
363 return _convert_image_util_error_code(__func__, err);
365 _handle->width = width;
366 _handle->height = height;
367 _handle->set_resize = true;
369 return _convert_image_util_error_code(__func__, err);
372 int image_util_transform_set_rotation(transformation_h handle, image_util_rotation_e rotation)
374 int err = MM_UTIL_ERROR_NONE;
375 transformation_s *_handle = (transformation_s *)handle;
377 image_util_debug("Set rotate_info [%d]", rotation);
379 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
381 err = mm_util_set_rotation(_handle->image_h, rotation);
382 if (err != MM_UTIL_ERROR_NONE) {
383 image_util_error("Error - Set rotation");
384 return _convert_image_util_error_code(__func__, err);
386 _handle->rotation = rotation;
387 _handle->set_rotate = true;
389 return _convert_image_util_error_code(__func__, err);
392 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)
394 int err = MM_UTIL_ERROR_NONE;
395 transformation_s *_handle = (transformation_s *)handle;
399 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
400 image_util_retvm_if((_handle->set_resize), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
402 dest_width = end_x - start_x;
403 dest_height = end_y - start_y;
405 image_util_debug("Set crop_info x[%d] y[%d] w[%d] h[%d]", start_x, start_y, dest_width, dest_height);
407 image_util_retvm_if((_image_util_check_resolution(dest_width, dest_height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest resolution");
408 err = mm_util_set_crop_area(_handle->image_h, start_x, start_y, end_x, end_y);
409 if (err != MM_UTIL_ERROR_NONE) {
410 image_util_error("Error - Set crop area");
411 return _convert_image_util_error_code(__func__, err);
413 _handle->start_x = start_x;
414 _handle->start_y = start_y;
415 _handle->end_x = end_x;
416 _handle->end_y = end_y;
417 _handle->set_crop = true;
419 return _convert_image_util_error_code(__func__, err);
422 int image_util_transform_get_colorspace(transformation_h handle, image_util_colorspace_e *colorspace)
424 int ret = IMAGE_UTIL_ERROR_NONE;
425 transformation_s *_handle = (transformation_s *)handle;
427 image_util_debug("Get colorspace_convert_info [%d]", colorspace);
429 if (_handle == NULL) {
430 image_util_error("Invalid Handle");
431 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
435 image_util_error("colorspace area parameter error");
436 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
439 if (!_handle->set_convert) {
440 image_util_error("Did not set colorspace before");
441 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
444 *colorspace = _handle->colorspace;
448 int image_util_transform_get_resolution(transformation_h handle, unsigned int *width, unsigned int *height)
450 int ret = IMAGE_UTIL_ERROR_NONE;
451 transformation_s *_handle = (transformation_s *)handle;
453 image_util_debug("Set resize_info w[%d] h[%d]", width, height);
455 if (_handle == NULL) {
456 image_util_error("Invalid Handle");
457 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
460 if (!width || !height) {
461 image_util_error("resolution area parameter error");
462 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
465 if (!_handle->set_resize) {
466 image_util_error("Did not set resolution before");
467 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
470 *width = _handle->width;
471 *height = _handle->height;
476 int image_util_transform_get_rotation(transformation_h handle, image_util_rotation_e *rotation)
478 int ret = IMAGE_UTIL_ERROR_NONE;
479 transformation_s *_handle = (transformation_s *)handle;
481 image_util_debug("Set rotate_info [%d]", rotation);
483 if (_handle == NULL) {
484 image_util_error("Invalid Handle");
485 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
489 image_util_error("rotation area parameter error");
490 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
493 if (!_handle->set_rotate) {
494 image_util_error("Did not set rotation before");
495 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
498 *rotation = _handle->rotation;
503 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)
505 int ret = IMAGE_UTIL_ERROR_NONE;
506 transformation_s *_handle = (transformation_s *)handle;
508 if (_handle == NULL) {
509 image_util_error("Invalid Handle");
510 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
513 if (!start_x || !start_y || !end_x || !end_y) {
514 image_util_error("crop area parameter error");
515 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
518 if (!_handle->set_crop) {
519 image_util_error("Did not set crop area before");
520 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
523 *start_x = _handle->start_x;
524 *start_y = _handle->start_y;
525 *end_x = _handle->end_x;
526 *end_y = _handle->end_y;
531 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
533 int err = MM_UTIL_ERROR_NONE;
534 transformation_s *_handle = (transformation_s *)handle;
536 image_util_debug("image_util_transform");
538 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
539 image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
540 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source");
541 image_util_retvm_if((!_handle->set_convert && !_handle->set_resize && !_handle->set_rotate && !_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform");
543 if (_handle->_util_cb != NULL) {
544 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
545 _handle->_util_cb = NULL;
547 _handle->_util_cb = (image_util_cb_s *)calloc(1, sizeof(image_util_cb_s));
548 image_util_retvm_if((_handle->_util_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
550 _handle->_util_cb->user_data = user_data;
551 _handle->_util_cb->image_processing_completed_cb = completed_cb;
553 if (_handle->_util_cb)
554 err = mm_util_transform(_handle->image_h, src, (mm_util_completed_callback)_image_util_transform_completed_cb, (void *)_handle->_util_cb);
556 return _convert_image_util_error_code(__func__, err);
559 int image_util_transform_destroy(transformation_h handle)
561 int err = MM_UTIL_ERROR_NONE;
562 transformation_s *_handle = (transformation_s *)handle;
564 image_util_debug("image_util_destroy");
566 if (_handle == NULL) {
567 image_util_error("Invalid Handle");
568 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
571 err = mm_util_destroy(_handle->image_h);
573 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
574 IMAGE_UTIL_SAFE_FREE(_handle);
576 return _convert_image_util_error_code(__func__, err);
579 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)
581 int err = MM_UTIL_ERROR_NONE;
583 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
584 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
585 image_util_retvm_if((dest_colorspace < 0 || dest_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dst_colorspace");
586 image_util_retvm_if((src_colorspace < 0 || src_colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid src_colorspace");
588 err = mm_util_convert_colorspace(src, width, height, _convert_colorspace_tbl[src_colorspace], dest, _convert_colorspace_tbl[dest_colorspace]);
590 return _convert_image_util_error_code(__func__, err);
594 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace , unsigned int *size)
596 int err = MM_UTIL_ERROR_NONE;
598 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
599 image_util_retvm_if((width <= 0 || height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid width or Invalid height");
600 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
602 err = mm_util_get_image_size(_convert_colorspace_tbl[colorspace], width, height, size);
603 return _convert_image_util_error_code(__func__, err);
606 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)
608 int err = MM_UTIL_ERROR_NONE;
610 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
611 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
612 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
613 image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
614 image_util_retvm_if((*dest_width <= 0 || *dest_height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest_width or Invalid dest_height");
616 unsigned int dest_w, dest_h;
617 dest_w = *dest_width;
618 dest_h = *dest_height;
619 err = mm_util_resize_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h);
620 if (err == MM_UTIL_ERROR_NONE) {
621 *dest_width = (int)dest_w;
622 *dest_height = (int)dest_h;
625 return _convert_image_util_error_code(__func__, err);
628 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)
630 int err = MM_UTIL_ERROR_NONE;
632 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
633 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
634 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
635 image_util_retvm_if((dest_rotation < 0 || dest_rotation > IMAGE_UTIL_ROTATION_FLIP_VERT), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid rotation");
636 image_util_retvm_if((dest_width == NULL || dest_height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest_width or dest_height is null");
638 unsigned int dest_w, dest_h;
639 err = mm_util_rotate_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], dest, &dest_w, &dest_h, dest_rotation);
640 if (err == MM_UTIL_ERROR_NONE) {
641 *dest_width = (int)dest_w;
642 *dest_height = (int)dest_h;
644 return _convert_image_util_error_code(__func__, err);
647 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)
649 int err = MM_UTIL_ERROR_NONE;
651 image_util_retvm_if((dest == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "dest is null");
652 image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "src is null");
653 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
654 image_util_retvm_if((width == NULL || height == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "width or height is null");
655 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");
657 unsigned int dest_w, dest_h;
660 err = mm_util_crop_image(src, src_width, src_height, _convert_colorspace_tbl[colorspace], x, y, &dest_w, &dest_h, dest);
661 if (err == MM_UTIL_ERROR_NONE) {
662 *width = (int)dest_w;
663 *height = (int)dest_h;
666 return _convert_image_util_error_code(__func__, err);
669 int image_util_decode_jpeg(const char *path, image_util_colorspace_e colorspace, unsigned char **image_buffer, int *width, int *height, unsigned int *size)
671 int err = MM_UTIL_ERROR_NONE;
673 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
674 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
675 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
676 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
677 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
678 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
680 mm_util_jpeg_yuv_data decoded;
681 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
683 err = mm_util_decode_from_jpeg_file(&decoded, path, _convert_encode_colorspace_tbl[colorspace]);
684 if (err == MM_UTIL_ERROR_NONE) {
685 *image_buffer = decoded.data;
687 *width = decoded.width;
689 *height = decoded.height;
691 *size = (unsigned int)decoded.size;
693 return _convert_image_util_error_code(__func__, err);
696 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)
698 int err = MM_UTIL_ERROR_NONE;
700 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
701 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
702 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
703 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
704 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
706 mm_util_jpeg_yuv_data decoded;
707 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
709 err = mm_util_decode_from_jpeg_memory(&decoded, (void *)jpeg_buffer, jpeg_size, _convert_encode_colorspace_tbl[colorspace]);
711 if (err == MM_UTIL_ERROR_NONE) {
712 *image_buffer = decoded.data;
714 *width = decoded.width;
716 *height = decoded.height;
718 *size = (unsigned int)decoded.size;
721 return _convert_image_util_error_code(__func__, err);
724 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)
726 int err = MM_UTIL_ERROR_NONE;
728 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
729 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
730 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
731 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
732 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
733 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
734 image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
736 mm_util_jpeg_yuv_data decoded;
737 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
739 err = mm_util_decode_from_jpeg_file_with_downscale(&decoded, path, _convert_encode_colorspace_tbl[colorspace], _convert_decode_scale_tbl[downscale]);
740 if (err == MM_UTIL_ERROR_NONE) {
741 *image_buffer = decoded.data;
743 *width = decoded.width;
745 *height = decoded.height;
747 *size = (unsigned int)decoded.size;
749 return _convert_image_util_error_code(__func__, err);
752 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)
754 int err = MM_UTIL_ERROR_NONE;
756 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
757 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
758 image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
759 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
760 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
761 image_util_retvm_if((downscale < 0 || downscale >= sizeof(_convert_decode_scale_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downsacle is invalid");
763 mm_util_jpeg_yuv_data decoded;
764 memset(&decoded, 0, sizeof(mm_util_jpeg_yuv_data));
766 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]);
768 if (err == MM_UTIL_ERROR_NONE) {
769 *image_buffer = decoded.data;
771 *width = decoded.width;
773 *height = decoded.height;
775 *size = (unsigned int)decoded.size;
778 return _convert_image_util_error_code(__func__, err);
781 int image_util_encode_jpeg(const unsigned char *buffer, int width, int height, image_util_colorspace_e colorspace, int quality, const char *path)
783 int err = MM_UTIL_ERROR_NONE;
785 image_util_retvm_if((path == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "path is null");
786 image_util_retvm_if((buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "buffer is null");
787 image_util_retvm_if((strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
788 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
789 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
791 err = mm_util_jpeg_encode_to_file(path, (void *)buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
792 return _convert_image_util_error_code(__func__, err);
795 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)
797 int err = MM_UTIL_ERROR_NONE;
800 image_util_retvm_if((jpeg_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_buffer is null");
801 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
802 image_util_retvm_if((jpeg_size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "jpeg_size is null");
803 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
804 image_util_retvm_if((_convert_encode_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
806 err = mm_util_jpeg_encode_to_memory((void **)jpeg_buffer, &isize, (void *)image_buffer, width, height, _convert_encode_colorspace_tbl[colorspace], quality);
807 if (err == MM_UTIL_ERROR_NONE)
808 *jpeg_size = (unsigned int)isize;
810 return _convert_image_util_error_code(__func__, err);
813 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)
815 int ret = MM_UTIL_ERROR_NONE;
817 image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer is null");
819 unsigned char r_color, g_color, b_color;
820 ret = mm_util_cv_extract_representative_color((void *)image_buffer, width, height, &r_color, & g_color, &b_color);
826 return _convert_image_util_error_code(__func__, ret);
829 int image_util_foreach_supported_colorspace(image_util_type_e image_type, image_util_supported_colorspace_cb callback, void *user_data)
833 image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
835 switch (image_type) {
836 case IMAGE_UTIL_JPEG:
837 /* RGB has higher precedence than YUV */
838 for (i = sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
839 if (_convert_jpeg_colorspace_tbl[i] != -1)
840 if (false == callback(i, user_data))
841 return IMAGE_UTIL_ERROR_NONE;
846 for (i = sizeof(_convert_png_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
847 if (_convert_png_colorspace_tbl[i] != -1)
848 if (false == callback(i, user_data))
849 return IMAGE_UTIL_ERROR_NONE;
854 for (i = sizeof(_convert_gif_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
855 if (_convert_gif_colorspace_tbl[i] != -1)
856 if (false == callback(i, user_data))
857 return IMAGE_UTIL_ERROR_NONE;
862 for (i = sizeof(_convert_bmp_colorspace_tbl) / sizeof(int) - 1; i >= 0; i--) {
863 if (_convert_bmp_colorspace_tbl[i] != -1)
864 if (false == callback(i, user_data))
865 return IMAGE_UTIL_ERROR_NONE;
870 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
873 return IMAGE_UTIL_ERROR_NONE;
876 static int _image_util_decode_create_jpeg_handle(decode_encode_s * handle)
878 int err = MM_UTIL_ERROR_NONE;
880 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
882 mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data));
883 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
885 handle->image_h = (MMHandleType) _handle;
886 handle->colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888;
887 handle->down_scale = sizeof(image_util_scale_e);
892 static int _image_util_decode_create_png_handle(decode_encode_s * handle)
894 int err = MM_UTIL_ERROR_NONE;
896 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
898 mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data));
899 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
901 mm_util_init_decode_png(_handle);
903 handle->image_h = (MMHandleType) _handle;
908 static int _image_util_decode_create_gif_handle(decode_encode_s * handle)
910 int err = MM_UTIL_ERROR_NONE;
912 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
914 mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data));
915 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
917 handle->image_h = (MMHandleType) _handle;
922 static int _image_util_decode_create_bmp_handle(decode_encode_s * handle)
924 int err = MM_UTIL_ERROR_NONE;
926 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
928 mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data));
929 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
931 handle->image_h = (MMHandleType) _handle;
936 int image_util_decode_create(image_util_decode_h * handle)
938 int err = MM_UTIL_ERROR_NONE;
940 image_util_debug("image_util_decode_create");
942 image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
944 decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
945 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
947 _handle->src_buffer = NULL;
948 _handle->dst_buffer = NULL;
949 _handle->path = NULL;
950 _handle->image_h = 0;
951 _handle->is_decode = TRUE;
952 _handle->image_type = -1;
954 *handle = (image_util_decode_h) _handle;
956 return _convert_image_util_error_code(__func__, err);
959 static char _JPEG_HEADER[] = { 0xFF, 0xD8 };
960 static char _PNG_HEADER[] = { 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a };
961 static char _GIF_HEADER[] = { 'G', 'I', 'F' };
962 static char _BMP_HEADER[] = { 'B', 'M' };
964 static int _image_util_decode_create_image_handle(image_util_decode_h handle, const unsigned char *src_buffer)
966 image_util_type_e image_type = -1;
971 image_util_type_e image_type;
973 { _JPEG_HEADER, sizeof(_JPEG_HEADER), IMAGE_UTIL_JPEG },
974 { _PNG_HEADER, sizeof(_PNG_HEADER), IMAGE_UTIL_PNG },
975 { _GIF_HEADER, sizeof(_GIF_HEADER), IMAGE_UTIL_GIF },
976 { _BMP_HEADER, sizeof(_BMP_HEADER), IMAGE_UTIL_BMP },
979 int err = MM_UTIL_ERROR_NONE;
980 decode_encode_s *_handle = (decode_encode_s *) handle;
982 if (_handle == NULL || _handle->is_decode == FALSE) {
983 image_util_error("Invalid Handle");
984 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
986 if (src_buffer == NULL) {
987 image_util_error("Invalid input buffer");
988 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
991 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)
995 image_type = image_header[i].image_type;
1000 _handle->image_type = image_type;
1002 switch (image_type) {
1003 case IMAGE_UTIL_JPEG:
1004 err = _image_util_decode_create_jpeg_handle(_handle);
1006 case IMAGE_UTIL_PNG:
1007 err = _image_util_decode_create_png_handle(_handle);
1009 case IMAGE_UTIL_GIF:
1010 err = _image_util_decode_create_gif_handle(_handle);
1012 case IMAGE_UTIL_BMP:
1013 err = _image_util_decode_create_bmp_handle(_handle);
1016 err = MM_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1020 if (err != MM_UTIL_ERROR_NONE) {
1021 image_util_error("Error - create image handle");
1022 IMAGE_UTIL_SAFE_FREE(_handle);
1023 return _convert_image_util_error_code(__func__, err);
1026 return _convert_image_util_error_code(__func__, err);
1029 int image_util_decode_set_input_path(image_util_decode_h handle, const char *path)
1031 int err = IMAGE_UTIL_ERROR_NONE;
1032 decode_encode_s *_handle = (decode_encode_s *) handle;
1034 unsigned char *src_buffer = NULL;
1036 if (_handle == NULL || _handle->is_decode == FALSE) {
1037 image_util_error("Invalid Handle");
1038 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1040 image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
1042 if (_handle->src_buffer)
1043 _handle->src_buffer = NULL;
1045 fp = fopen(path, "r");
1047 image_util_error("File open failed");
1048 return IMAGE_UTIL_ERROR_NO_SUCH_FILE;
1050 src_buffer = (void *)malloc(sizeof(_PNG_HEADER));
1051 if (!fread(src_buffer, 1, sizeof(_PNG_HEADER), fp)) {
1052 image_util_error("File read failed");
1056 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
1059 err = _image_util_decode_create_image_handle(_handle, src_buffer);
1065 _handle->path = path;
1070 int image_util_decode_set_input_buffer(image_util_decode_h handle, const unsigned char *src_buffer, unsigned long long src_size)
1072 int err = IMAGE_UTIL_ERROR_NONE;
1073 decode_encode_s *_handle = (decode_encode_s *) handle;
1075 if (_handle == NULL || _handle->is_decode == FALSE) {
1076 image_util_error("Invalid Handle");
1077 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1079 if (src_buffer == NULL || src_size == 0) {
1080 image_util_error("Invalid input buffer");
1081 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1085 _handle->path = NULL;
1087 err = _image_util_decode_create_image_handle(_handle, src_buffer);
1089 _handle->src_buffer = (void *)src_buffer;
1090 _handle->src_size = src_size;
1095 int image_util_decode_set_output_buffer(image_util_decode_h handle, unsigned char **dst_buffer)
1097 int err = IMAGE_UTIL_ERROR_NONE;
1098 decode_encode_s *_handle = (decode_encode_s *) handle;
1100 if (_handle == NULL || _handle->is_decode == FALSE) {
1101 image_util_error("Invalid Handle");
1102 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1104 if (dst_buffer == NULL) {
1105 image_util_error("Invalid output buffer");
1106 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1109 _handle->dst_buffer = (void **)dst_buffer;
1114 int image_util_decode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace)
1116 int err = IMAGE_UTIL_ERROR_NONE;
1117 decode_encode_s *_handle = (decode_encode_s *) handle;
1119 if (_handle == NULL || _handle->is_decode == FALSE) {
1120 image_util_error("Invalid Handle");
1121 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1124 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
1125 switch (_handle->image_type) {
1126 case IMAGE_UTIL_JPEG:
1127 image_util_retvm_if((_convert_jpeg_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1129 case IMAGE_UTIL_PNG:
1130 image_util_retvm_if((_convert_png_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1132 case IMAGE_UTIL_GIF:
1133 image_util_retvm_if((_convert_gif_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1135 case IMAGE_UTIL_BMP:
1136 image_util_retvm_if((_convert_bmp_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1139 image_util_error("Invalid image type");
1140 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1143 _handle->colorspace = colorspace;
1148 int image_util_decode_set_jpeg_downscale(image_util_encode_h handle, image_util_scale_e down_scale)
1150 int err = IMAGE_UTIL_ERROR_NONE;
1151 decode_encode_s *_handle = (decode_encode_s *) handle;
1153 if (_handle == NULL || _handle->is_decode == FALSE) {
1154 image_util_error("Invalid Handle");
1155 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1157 if (_handle->image_type != IMAGE_UTIL_JPEG) {
1158 image_util_error("Wrong image format");
1159 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1161 image_util_retvm_if((down_scale < 0 || down_scale >= sizeof(image_util_scale_e)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "downscale is invalid");
1163 _handle->down_scale = down_scale;
1168 static int _image_util_decode_internal(decode_encode_s * _handle)
1170 int err = MM_UTIL_ERROR_NONE;
1172 switch (_handle->image_type) {
1173 case IMAGE_UTIL_JPEG:
1175 mm_util_jpeg_yuv_data *jpeg_data;
1177 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1178 if (jpeg_data == NULL) {
1179 image_util_error("Invalid jpeg data");
1180 return MM_UTIL_ERROR_INVALID_PARAMETER;
1183 if (_handle->path) {
1184 if (_handle->down_scale < sizeof(image_util_scale_e))
1185 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]);
1187 err = mm_util_decode_from_jpeg_file(jpeg_data, _handle->path, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
1190 if (_handle->down_scale < sizeof(image_util_scale_e))
1191 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]);
1193 err = mm_util_decode_from_jpeg_memory(jpeg_data, _handle->src_buffer, _handle->src_size, _convert_jpeg_colorspace_tbl[_handle->colorspace]);
1196 if (err == MM_UTIL_ERROR_NONE) {
1197 *(_handle->dst_buffer) = jpeg_data->data;
1198 _handle->dst_size = (unsigned long long)jpeg_data->size;
1199 _handle->width = jpeg_data->width;
1200 _handle->height = jpeg_data->height;
1204 case IMAGE_UTIL_PNG:
1206 mm_util_png_data *png_data;
1208 png_data = (mm_util_png_data *) _handle->image_h;
1209 if (png_data == NULL) {
1210 image_util_error("Invalid png data");
1211 return MM_UTIL_ERROR_INVALID_PARAMETER;
1215 err = mm_util_decode_from_png_file(png_data, _handle->path);
1217 err = mm_util_decode_from_png_memory(png_data, &_handle->src_buffer, _handle->src_size);
1219 if (err == MM_UTIL_ERROR_NONE) {
1220 *(_handle->dst_buffer) = png_data->data;
1221 _handle->dst_size = png_data->size;
1222 _handle->width = png_data->width;
1223 _handle->height = png_data->height;
1227 case IMAGE_UTIL_GIF:
1229 mm_util_gif_data *gif_data;
1231 gif_data = (mm_util_gif_data *) _handle->image_h;
1232 if (gif_data == NULL) {
1233 image_util_error("Invalid gif data");
1234 return MM_UTIL_ERROR_INVALID_PARAMETER;
1238 err = mm_util_decode_from_gif_file(gif_data, _handle->path);
1240 err = mm_util_decode_from_gif_memory(gif_data, &_handle->src_buffer);
1242 if (err == MM_UTIL_ERROR_NONE) {
1243 *(_handle->dst_buffer) = gif_data->frames[0].data;
1244 _handle->dst_size = gif_data->size;
1245 _handle->width = gif_data->width;
1246 _handle->height = gif_data->height;
1250 case IMAGE_UTIL_BMP:
1252 mm_util_bmp_data *bmp_data;
1254 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1255 if (bmp_data == NULL) {
1256 image_util_error("Invalid bmp data");
1257 return MM_UTIL_ERROR_INVALID_PARAMETER;
1261 err = mm_util_decode_from_bmp_file(bmp_data, _handle->path);
1263 err = mm_util_decode_from_bmp_memory(bmp_data, &_handle->src_buffer, _handle->src_size);
1265 if (err == MM_UTIL_ERROR_NONE) {
1266 *(_handle->dst_buffer) = bmp_data->data;
1267 _handle->dst_size = bmp_data->size;
1268 _handle->width = bmp_data->width;
1269 _handle->height = bmp_data->height;
1274 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1281 int image_util_decode_run(image_util_decode_h handle, unsigned long *width, unsigned long *height, unsigned long long *size)
1283 int err = MM_UTIL_ERROR_NONE;
1284 decode_encode_s *_handle = (decode_encode_s *) handle;
1286 if (_handle == NULL || _handle->is_decode == FALSE) {
1287 image_util_error("Invalid Handle");
1288 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1290 if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
1291 image_util_error("Invalid input/output");
1292 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1295 err = _image_util_decode_internal(_handle);
1297 if (err != MM_UTIL_ERROR_NONE) {
1298 image_util_error("Error - decode run");
1299 return _convert_image_util_error_code(__func__, err);
1303 *width = _handle->width;
1305 *height = _handle->height;
1307 *size = _handle->dst_size;
1309 return _convert_image_util_error_code(__func__, err);
1312 gpointer _image_util_decode_thread(gpointer data)
1314 decode_encode_s *_handle = (decode_encode_s *) data;
1315 int err = MM_UTIL_ERROR_NONE;
1316 gint64 end_time = 0;
1319 image_util_error("[ERROR] - handle");
1323 while (!_handle->is_finish) {
1324 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1325 image_util_debug("waiting...");
1326 g_mutex_lock(&(_handle->thread_mutex));
1327 g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
1328 image_util_debug("<=== get run decode thread signal");
1329 g_mutex_unlock(&(_handle->thread_mutex));
1331 if (_handle->is_finish) {
1332 image_util_debug("exit loop");
1336 err = _image_util_decode_internal(_handle);
1337 if(err == MM_UTIL_ERROR_NONE) {
1338 image_util_debug("Success - decode_internal");
1340 image_util_error("Error - decode_internal");
1342 if (_handle->_decode_cb) {
1343 image_util_debug("completed_cb");
1344 _handle->is_finish = TRUE;
1345 _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);
1349 image_util_debug("exit thread");
1354 static int _image_util_decode_create_thread(decode_encode_s * handle)
1356 int err = MM_UTIL_ERROR_NONE;
1358 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1360 g_mutex_init(&(handle->thread_mutex));
1362 g_cond_init(&(handle->thread_cond));
1365 handle->thread = g_thread_new("decode_thread", (GThreadFunc) _image_util_decode_thread, (gpointer) handle);
1366 if (!handle->thread) {
1367 image_util_error("ERROR - create thread");
1368 g_mutex_clear(&(handle->thread_mutex));
1370 g_cond_clear(&(handle->thread_cond));
1371 return MM_UTIL_ERROR_INVALID_OPERATION;
1377 int image_util_decode_run_async(image_util_decode_h handle, image_util_decode_completed_cb completed_cb, void *user_data)
1379 int err = MM_UTIL_ERROR_NONE;
1380 decode_encode_s *_handle = (decode_encode_s *) handle;
1382 if (_handle == NULL || _handle->is_decode == FALSE) {
1383 image_util_error("Invalid Handle");
1384 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1386 if ((_handle->path == NULL && _handle->src_buffer == NULL) || _handle->dst_buffer == NULL) {
1387 image_util_error("Invalid input/output");
1388 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1390 image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
1392 if (_handle->_decode_cb != NULL) {
1393 IMAGE_UTIL_SAFE_FREE(_handle->_decode_cb);
1394 _handle->_decode_cb = NULL;
1396 _handle->_decode_cb = (decode_cb_s *) calloc(1, sizeof(decode_cb_s));
1397 image_util_retvm_if((_handle->_decode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
1399 _handle->_decode_cb->user_data = user_data;
1400 _handle->_decode_cb->image_decode_completed_cb = completed_cb;
1402 err = _image_util_decode_create_thread(_handle);
1404 return _convert_image_util_error_code(__func__, err);
1407 int image_util_decode_destroy(image_util_decode_h handle)
1409 int err = IMAGE_UTIL_ERROR_NONE;
1410 decode_encode_s *_handle = (decode_encode_s *) handle;
1412 image_util_debug("image_util_encode_png_destroy");
1414 if (_handle == NULL || _handle->is_decode == FALSE) {
1415 image_util_error("Invalid Handle");
1416 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1419 switch (_handle->image_type) {
1420 case IMAGE_UTIL_JPEG:
1422 mm_util_jpeg_yuv_data *jpeg_data;
1424 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1425 if (jpeg_data == NULL) {
1426 image_util_error("Invalid jpeg data");
1427 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1429 IMAGE_UTIL_SAFE_FREE(jpeg_data);
1432 case IMAGE_UTIL_PNG:
1434 mm_util_png_data *png_data;
1436 png_data = (mm_util_png_data *) _handle->image_h;
1437 if (png_data == NULL) {
1438 image_util_error("Invalid png data");
1439 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1441 IMAGE_UTIL_SAFE_FREE(png_data);
1444 case IMAGE_UTIL_GIF:
1446 mm_util_gif_data *gif_data;
1448 gif_data = (mm_util_gif_data *) _handle->image_h;
1449 if (gif_data == NULL) {
1450 image_util_error("Invalid gif data");
1451 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1453 IMAGE_UTIL_SAFE_FREE(gif_data);
1456 case IMAGE_UTIL_BMP:
1458 mm_util_bmp_data *bmp_data;
1460 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1461 if (bmp_data == NULL) {
1462 image_util_error("Invalid bmp data");
1463 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1465 IMAGE_UTIL_SAFE_FREE(bmp_data);
1472 /* g_thread_exit(handle->thread); */
1473 if (_handle->thread) {
1474 _handle->is_finish = TRUE;
1475 g_mutex_lock(&(_handle->thread_mutex));
1476 g_cond_signal(&(_handle->thread_cond));
1477 image_util_debug("===> send signal(finish) to decode_thread");
1478 g_mutex_unlock(&(_handle->thread_mutex));
1480 g_thread_join(_handle->thread);
1482 g_mutex_clear(&(_handle->thread_mutex));
1484 g_cond_clear(&(_handle->thread_cond));
1487 IMAGE_UTIL_SAFE_FREE(_handle);
1492 static int _image_util_encode_create_jpeg_handle(decode_encode_s * handle)
1494 int err = MM_UTIL_ERROR_NONE;
1496 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1498 mm_util_jpeg_yuv_data *_handle = (mm_util_jpeg_yuv_data *) calloc(1, sizeof(mm_util_jpeg_yuv_data));
1499 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1501 handle->image_h = (MMHandleType) _handle;
1502 handle->colorspace = IMAGE_UTIL_COLORSPACE_RGBA8888;
1503 handle->quality = 20;
1508 static int _image_util_encode_create_png_handle(decode_encode_s * handle)
1510 int err = MM_UTIL_ERROR_NONE;
1512 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1514 mm_util_png_data *_handle = (mm_util_png_data *) calloc(1, sizeof(mm_util_png_data));
1515 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1517 mm_util_init_encode_png(_handle);
1519 handle->image_h = (MMHandleType) _handle;
1524 static int _image_util_encode_create_gif_handle(decode_encode_s * handle)
1526 int err = MM_UTIL_ERROR_NONE;
1528 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1530 mm_util_gif_data *_handle = (mm_util_gif_data *) calloc(1, sizeof(mm_util_gif_data));
1531 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1533 _handle->frames = (mm_util_gif_frame_data *) calloc(1, sizeof(mm_util_gif_frame_data));
1534 if (_handle->frames == NULL) {
1535 image_util_error("Error - OUT_OF_MEMORY");
1536 IMAGE_UTIL_SAFE_FREE(_handle);
1537 return MM_UTIL_ERROR_OUT_OF_MEMORY;
1540 mm_util_gif_encode_set_image_count(_handle, 1);
1541 handle->image_h = (MMHandleType) _handle;
1546 static int _image_util_encode_create_bmp_handle(decode_encode_s * handle)
1548 int err = MM_UTIL_ERROR_NONE;
1550 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1552 mm_util_bmp_data *_handle = (mm_util_bmp_data *) calloc(1, sizeof(mm_util_bmp_data));
1553 image_util_retvm_if((_handle == NULL), MM_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", MM_UTIL_ERROR_OUT_OF_MEMORY);
1555 handle->image_h = (MMHandleType) _handle;
1560 int image_util_encode_create(image_util_type_e image_type, image_util_encode_h * handle)
1562 int err = MM_UTIL_ERROR_NONE;
1564 image_util_debug("image_util_encode_create");
1566 image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
1568 decode_encode_s *_handle = (decode_encode_s *) calloc(1, sizeof(decode_encode_s));
1569 image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
1571 _handle->image_type = image_type;
1572 _handle->src_buffer = NULL;
1573 _handle->dst_buffer = NULL;
1574 _handle->path = NULL;
1575 _handle->image_h = 0;
1576 _handle->is_decode = FALSE;
1578 switch (image_type) {
1579 case IMAGE_UTIL_JPEG:
1580 err = _image_util_encode_create_jpeg_handle(_handle);
1582 case IMAGE_UTIL_PNG:
1583 err = _image_util_encode_create_png_handle(_handle);
1585 case IMAGE_UTIL_GIF:
1586 err = _image_util_encode_create_gif_handle(_handle);
1588 case IMAGE_UTIL_BMP:
1589 err = _image_util_encode_create_bmp_handle(_handle);
1592 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1596 if (err != MM_UTIL_ERROR_NONE) {
1597 image_util_error("Error - create image handle");
1598 IMAGE_UTIL_SAFE_FREE(_handle);
1599 return _convert_image_util_error_code(__func__, err);
1602 *handle = (image_util_encode_h) _handle;
1604 return _convert_image_util_error_code(__func__, err);
1607 int image_util_encode_set_resolution(image_util_encode_h handle, unsigned long width, unsigned long height)
1609 int err = IMAGE_UTIL_ERROR_NONE;
1610 decode_encode_s *_handle = (decode_encode_s *) handle;
1612 if (_handle == NULL || _handle->is_decode == TRUE) {
1613 image_util_error("Invalid Handle");
1614 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1616 image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
1618 switch (_handle->image_type) {
1619 case IMAGE_UTIL_JPEG:
1621 mm_util_jpeg_yuv_data *jpeg_data;
1623 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
1624 if (jpeg_data == NULL) {
1625 image_util_error("Invalid jpeg data");
1626 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1628 jpeg_data->width = width;
1629 jpeg_data->height = height;
1632 case IMAGE_UTIL_PNG:
1634 mm_util_png_data *png_data;
1636 png_data = (mm_util_png_data *) _handle->image_h;
1637 if (png_data == NULL) {
1638 image_util_error("Invalid png data");
1639 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1641 mm_util_png_encode_set_width(png_data, width);
1642 mm_util_png_encode_set_height(png_data, height);
1645 case IMAGE_UTIL_GIF:
1647 mm_util_gif_data *gif_data;
1649 gif_data = (mm_util_gif_data *) _handle->image_h;
1650 if (gif_data == NULL) {
1651 image_util_error("Invalid gif data");
1652 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1654 mm_util_gif_encode_set_width(gif_data, width);
1655 mm_util_gif_encode_set_height(gif_data, height);
1658 case IMAGE_UTIL_BMP:
1660 mm_util_bmp_data *bmp_data;
1662 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1663 if (bmp_data == NULL) {
1664 image_util_error("Invalid bmp data");
1665 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1667 mm_util_bmp_encode_set_width(bmp_data, width);
1668 mm_util_bmp_encode_set_height(bmp_data, height);
1672 err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1676 _handle->width = width;
1677 _handle->height = height;
1682 int image_util_encode_set_colorspace(image_util_encode_h handle, image_util_colorspace_e colorspace)
1684 int err = IMAGE_UTIL_ERROR_NONE;
1685 decode_encode_s *_handle = (decode_encode_s *) handle;
1687 if (_handle == NULL || _handle->is_decode == TRUE) {
1688 image_util_error("Invalid Handle");
1689 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1692 image_util_retvm_if((colorspace < 0 || colorspace >= sizeof(_convert_jpeg_colorspace_tbl) / sizeof(int)), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
1693 switch (_handle->image_type) {
1694 case IMAGE_UTIL_JPEG:
1695 image_util_retvm_if((_convert_jpeg_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1697 case IMAGE_UTIL_PNG:
1698 image_util_retvm_if((_convert_png_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1700 case IMAGE_UTIL_GIF:
1701 image_util_retvm_if((_convert_gif_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1703 case IMAGE_UTIL_BMP:
1704 image_util_retvm_if((_convert_bmp_colorspace_tbl[colorspace] == -1), IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT, "not supported format");
1707 image_util_error("Invalid image type");
1708 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1711 _handle->colorspace = colorspace;
1716 int image_util_encode_set_jpeg_quality(image_util_encode_h handle, int quality)
1718 int err = IMAGE_UTIL_ERROR_NONE;
1719 decode_encode_s *_handle = (decode_encode_s *) handle;
1721 if (_handle == NULL || _handle->is_decode == TRUE) {
1722 image_util_error("Invalid Handle");
1723 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1725 if (_handle->image_type != IMAGE_UTIL_JPEG) {
1726 image_util_error("Wrong image format");
1727 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1729 image_util_retvm_if((quality <= 0 || quality > 100), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid quality");
1731 _handle->quality = quality;
1736 int image_util_encode_set_png_compression(image_util_encode_h handle, image_util_png_compression_e compression)
1738 int err = IMAGE_UTIL_ERROR_NONE;
1739 decode_encode_s *_handle = (decode_encode_s *) handle;
1740 mm_util_png_data *png_data;
1742 if (_handle == NULL || _handle->is_decode == TRUE) {
1743 image_util_error("Invalid Handle");
1744 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1746 if (_handle->image_type != IMAGE_UTIL_PNG) {
1747 image_util_error("Wrong image format");
1748 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1750 image_util_retvm_if((compression < IMAGE_UTIL_PNG_COMPRESSION_0 || compression > IMAGE_UTIL_PNG_COMPRESSION_9), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid compression value");
1752 png_data = (mm_util_png_data *) _handle->image_h;
1753 if (png_data == NULL) {
1754 image_util_error("Invalid png data");
1755 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1758 mm_util_png_encode_set_compression_level(png_data, compression);
1763 int image_util_encode_set_input_buffer(image_util_encode_h handle, const unsigned char *src_buffer)
1765 int err = IMAGE_UTIL_ERROR_NONE;
1766 decode_encode_s *_handle = (decode_encode_s *) handle;
1768 if (_handle == NULL || _handle->is_decode == TRUE) {
1769 image_util_error("Invalid Handle");
1770 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1772 if (src_buffer == NULL) {
1773 image_util_error("Invalid input buffer");
1774 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1777 _handle->src_buffer = (void *)src_buffer;
1782 int image_util_encode_set_output_path(image_util_encode_h handle, const char *path)
1784 int err = IMAGE_UTIL_ERROR_NONE;
1785 decode_encode_s *_handle = (decode_encode_s *) handle;
1787 if (_handle == NULL || _handle->is_decode == TRUE) {
1788 image_util_error("Invalid Handle");
1789 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1791 image_util_retvm_if((path == NULL || strlen(path) == 0), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "Invalid path");
1793 if (_handle->dst_buffer)
1794 _handle->dst_buffer = NULL;
1796 _handle->path = path;
1801 int image_util_encode_set_output_buffer(image_util_encode_h handle, unsigned char **dst_buffer)
1803 int err = IMAGE_UTIL_ERROR_NONE;
1804 decode_encode_s *_handle = (decode_encode_s *) handle;
1806 if (_handle == NULL || _handle->is_decode == TRUE) {
1807 image_util_error("Invalid Handle");
1808 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1810 if (_handle->image_type == IMAGE_UTIL_BMP) {
1811 image_util_error("BMP library does not support encoding to memory");
1812 return IMAGE_UTIL_ERROR_NOT_SUPPORTED_FORMAT;
1814 if (dst_buffer == NULL) {
1815 image_util_error("Invalid output buffer");
1816 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1820 _handle->path = NULL;
1822 _handle->dst_buffer = (void **)dst_buffer;
1827 static int _image_util_encode_internal(decode_encode_s * _handle)
1829 int err = MM_UTIL_ERROR_NONE;
1831 switch (_handle->image_type) {
1832 case IMAGE_UTIL_JPEG:
1835 err = mm_util_jpeg_encode_to_file (_handle->path, _handle->src_buffer, _handle->width, _handle->height, _convert_jpeg_colorspace_tbl[_handle->colorspace], _handle->quality);
1837 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);
1840 case IMAGE_UTIL_PNG:
1842 mm_util_png_data *png_data;
1844 png_data = (mm_util_png_data *) _handle->image_h;
1845 if (png_data == NULL) {
1846 image_util_error("Invalid png data");
1847 return MM_UTIL_ERROR_INVALID_PARAMETER;
1851 err = mm_util_encode_to_png_file(&(_handle->src_buffer), png_data, _handle->path);
1853 err = mm_util_encode_to_png_memory(&(_handle->src_buffer), png_data);
1855 if (err == MM_UTIL_ERROR_NONE) {
1856 if (_handle->dst_buffer)
1857 *(_handle->dst_buffer) = png_data->data;
1858 _handle->dst_size = png_data->size;
1859 _handle->width = png_data->width;
1860 _handle->height = png_data->height;
1864 case IMAGE_UTIL_GIF:
1866 mm_util_gif_data *gif_data;
1867 void *dst_buffer = NULL;
1869 gif_data = (mm_util_gif_data *) _handle->image_h;
1870 if (gif_data == NULL || gif_data->frames == NULL) {
1871 image_util_error("Invalid gif data");
1872 return MM_UTIL_ERROR_INVALID_PARAMETER;
1875 gif_data->frames[0].data = _handle->src_buffer;
1877 err = mm_util_encode_gif_to_file(gif_data, _handle->path);
1879 err = mm_util_encode_gif_to_memory(gif_data, &dst_buffer);
1881 if (err == MM_UTIL_ERROR_NONE) {
1882 if (_handle->dst_buffer)
1883 *(_handle->dst_buffer) = (unsigned char *)dst_buffer;
1884 _handle->dst_size = gif_data->size;
1885 _handle->width = gif_data->width;
1886 _handle->height = gif_data->height;
1890 case IMAGE_UTIL_BMP:
1892 mm_util_bmp_data *bmp_data;
1894 bmp_data = (mm_util_bmp_data *) _handle->image_h;
1895 if (bmp_data == NULL) {
1896 image_util_error("Invalid bmp data");
1897 return MM_UTIL_ERROR_INVALID_PARAMETER;
1900 bmp_data->data = _handle->src_buffer;
1902 err = mm_util_encode_bmp_to_file(bmp_data, _handle->path);
1904 image_util_error("Not yet implemented");
1905 return MM_UTIL_ERROR_INVALID_PARAMETER;
1908 if (err == MM_UTIL_ERROR_NONE) {
1909 if (_handle->dst_buffer)
1910 *(_handle->dst_buffer) = bmp_data->data;
1911 _handle->dst_size = bmp_data->size;
1912 _handle->width = bmp_data->width;
1913 _handle->height = bmp_data->height;
1918 err = MM_UTIL_ERROR_INVALID_PARAMETER;
1925 int image_util_encode_run(image_util_encode_h handle, unsigned long long *size)
1927 int err = MM_UTIL_ERROR_NONE;
1928 decode_encode_s *_handle = (decode_encode_s *) handle;
1930 if (_handle == NULL || _handle->is_decode == TRUE) {
1931 image_util_error("Invalid Handle");
1932 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1934 if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
1935 image_util_error("Invalid input/output");
1936 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
1938 image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
1940 err = _image_util_encode_internal(_handle);
1942 if (err != MM_UTIL_ERROR_NONE) {
1943 image_util_error("Error - encode run");
1944 return _convert_image_util_error_code(__func__, err);
1948 *size = _handle->dst_size;
1950 return _convert_image_util_error_code(__func__, err);
1953 gpointer _image_util_encode_thread(gpointer data)
1955 decode_encode_s *_handle = (decode_encode_s *) data;
1956 int err = MM_UTIL_ERROR_NONE;
1957 gint64 end_time = 0;
1960 image_util_error("[ERROR] - handle");
1964 while (!_handle->is_finish) {
1965 end_time = g_get_monotonic_time() + 1 * G_TIME_SPAN_SECOND;
1966 image_util_debug("waiting...");
1967 g_mutex_lock(&(_handle->thread_mutex));
1968 g_cond_wait_until(&(_handle->thread_cond), &(_handle->thread_mutex), end_time);
1969 image_util_debug("<=== get run encode thread signal");
1970 g_mutex_unlock(&(_handle->thread_mutex));
1972 if (_handle->is_finish) {
1973 image_util_debug("exit loop");
1977 err = _image_util_encode_internal(_handle);
1978 if(err == MM_UTIL_ERROR_NONE) {
1979 image_util_debug("Success - encode_internal");
1981 image_util_error("Error - encode_internal");
1983 if (_handle->_encode_cb) {
1984 image_util_debug("completed_cb");
1985 _handle->is_finish = TRUE;
1986 _handle->_encode_cb->image_encode_completed_cb(_convert_image_util_error_code(__func__, err), _handle->_encode_cb->user_data, _handle->dst_size);
1990 image_util_debug("exit thread");
1995 static int _image_util_encode_create_thread(decode_encode_s * handle)
1997 int ret = MM_UTIL_ERROR_NONE;
1999 image_util_retvm_if((handle == NULL), MM_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
2001 g_mutex_init(&(handle->thread_mutex));
2003 g_cond_init(&(handle->thread_cond));
2006 handle->thread = g_thread_new("encode_thread", (GThreadFunc) _image_util_encode_thread, (gpointer) handle);
2007 if (!handle->thread) {
2008 image_util_error("ERROR - create thread");
2009 g_mutex_clear(&(handle->thread_mutex));
2011 g_cond_clear(&(handle->thread_cond));
2012 return MM_UTIL_ERROR_INVALID_OPERATION;
2018 int image_util_encode_run_async(image_util_encode_h handle, image_util_encode_completed_cb completed_cb, void *user_data)
2020 int err = MM_UTIL_ERROR_NONE;
2021 decode_encode_s *_handle = (decode_encode_s *) handle;
2023 if (_handle == NULL || _handle->is_decode == TRUE) {
2024 image_util_error("Invalid Handle");
2025 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2027 if ((_handle->path == NULL && _handle->dst_buffer == NULL) || _handle->src_buffer == NULL) {
2028 image_util_error("Invalid input/output");
2029 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2031 image_util_retvm_if((_image_util_check_resolution(_handle->width, _handle->height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
2033 image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
2035 if (_handle->_encode_cb != NULL) {
2036 IMAGE_UTIL_SAFE_FREE(_handle->_encode_cb);
2037 _handle->_encode_cb = NULL;
2039 _handle->_encode_cb = (encode_cb_s *) calloc(1, sizeof(encode_cb_s));
2040 image_util_retvm_if((_handle->_encode_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
2042 _handle->_encode_cb->user_data = user_data;
2043 _handle->_encode_cb->image_encode_completed_cb = completed_cb;
2045 err = _image_util_encode_create_thread(_handle);
2047 return _convert_image_util_error_code(__func__, err);
2050 int image_util_encode_destroy(image_util_encode_h handle)
2052 int err = IMAGE_UTIL_ERROR_NONE;
2053 decode_encode_s *_handle = (decode_encode_s *) handle;
2055 image_util_debug("image_util_encode_destroy");
2057 if (_handle == NULL || _handle->is_decode == TRUE) {
2058 image_util_error("Invalid Handle");
2059 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2062 switch (_handle->image_type) {
2063 case IMAGE_UTIL_JPEG:
2065 mm_util_jpeg_yuv_data *jpeg_data;
2067 jpeg_data = (mm_util_jpeg_yuv_data *) _handle->image_h;
2068 if (jpeg_data == NULL) {
2069 image_util_error("Invalid jpeg data");
2070 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2072 IMAGE_UTIL_SAFE_FREE(jpeg_data);
2075 case IMAGE_UTIL_PNG:
2077 mm_util_png_data *png_data;
2079 png_data = (mm_util_png_data *) _handle->image_h;
2080 if (png_data == NULL) {
2081 image_util_error("Invalid png data");
2082 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2084 IMAGE_UTIL_SAFE_FREE(png_data);
2087 case IMAGE_UTIL_GIF:
2089 mm_util_gif_data *gif_data;
2091 gif_data = (mm_util_gif_data *) _handle->image_h;
2092 if (gif_data == NULL) {
2093 image_util_error("Invalid gif data");
2094 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2096 IMAGE_UTIL_SAFE_FREE(gif_data->frames);
2097 IMAGE_UTIL_SAFE_FREE(gif_data);
2100 case IMAGE_UTIL_BMP:
2102 mm_util_bmp_data *bmp_data;
2104 bmp_data = (mm_util_bmp_data *) _handle->image_h;
2105 if (bmp_data == NULL) {
2106 image_util_error("Invalid bmp data");
2107 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2109 IMAGE_UTIL_SAFE_FREE(bmp_data);
2113 err = IMAGE_UTIL_ERROR_INVALID_PARAMETER;
2117 /* g_thread_exit(handle->thread); */
2118 if (_handle->thread) {
2119 _handle->is_finish = TRUE;
2120 g_mutex_lock(&(_handle->thread_mutex));
2121 g_cond_signal(&(_handle->thread_cond));
2122 image_util_debug("===> send signal(finish) to decode_thread");
2123 g_mutex_unlock(&(_handle->thread_mutex));
2125 g_thread_join(_handle->thread);
2127 g_mutex_clear(&(_handle->thread_mutex));
2129 g_cond_clear(&(_handle->thread_cond));
2132 IMAGE_UTIL_SAFE_FREE(_handle);