3f27342d0c2f435cdb73a98d1a6f8dc7dce5ea0e
[platform/core/api/image-util.git] / src / image_util.c
1 /*
2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17 #include <mm_util_imgp.h>
18
19 #include <image_util.h>
20 #include <image_util_private.h>
21
22 static void _image_util_transform_completed_cb(media_packet_h * dst, int error, void *user_data)
23 {
24         int error_value = IMAGE_UTIL_ERROR_NONE;
25         image_util_cb_s *_util_cb = (image_util_cb_s *) user_data;
26
27         if ((_util_cb != NULL) && (_util_cb->image_processing_completed_cb != NULL)) {
28                 error_value = _image_util_error_convert(error);
29                 _util_cb->image_processing_completed_cb(dst, error_value, _util_cb->user_data);
30         }
31
32         return;
33 }
34
35 static int _image_util_create_transform_handle(transformation_s * handle)
36 {
37         int err = MM_UTIL_ERROR_NONE;
38         mm_util_imgp_h image_h;
39
40         err = mm_util_create(&image_h);
41         if (err != MM_UTIL_ERROR_NONE) {
42                 image_util_error("Error - mm_util_create");
43                 return _convert_image_util_error_code(__func__, err);
44         }
45
46         handle->image_h = image_h;
47
48         return _convert_image_util_error_code(__func__, err);
49 }
50
51 int image_util_foreach_supported_jpeg_colorspace(image_util_supported_jpeg_colorspace_cb callback, void *user_data)
52 {
53         int idx = 0;
54
55         DEPRECATION_LOGW("image_util_foreach_supported_jpeg_colorspace()", "image_util_foreach_supported_colorspace()");
56
57         image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
58
59         /* RGB has higher precedence than YUV */
60         for (idx = (int)(NUM_OF_COLORSPACE - 1); idx >= 0; idx--) {
61                 if (is_supported_colorspace(idx, IMAGE_UTIL_JPEG))
62                         if (false == callback(idx, user_data))
63                                 return IMAGE_UTIL_ERROR_NONE;
64
65         }
66
67         return IMAGE_UTIL_ERROR_NONE;
68 }
69
70 int image_util_transform_create(transformation_h * handle)
71 {
72         int err = MM_UTIL_ERROR_NONE;
73
74         image_util_debug("image_util_create");
75
76         image_util_retvm_if((handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
77
78         transformation_s *_handle = (transformation_s *) calloc(1, sizeof(transformation_s));
79         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY(0x%08x)", IMAGE_UTIL_ERROR_OUT_OF_MEMORY);
80
81         _handle->colorspace = _NOT_SUPPORTED_COLORSPACE;
82         _handle->_util_cb = NULL;
83         _handle->image_h = 0;
84         _handle->hardware_acceleration = false;
85         _handle->set_convert = false;
86         _handle->set_resize = false;
87         _handle->set_rotate = false;
88         _handle->set_crop = false;
89
90         err = _image_util_create_transform_handle(_handle);
91         if (err != MM_UTIL_ERROR_NONE) {
92                 image_util_error("Error - create transform handle");
93                 IMAGE_UTIL_SAFE_FREE(_handle);
94                 return _convert_image_util_error_code(__func__, err);
95         }
96
97         *handle = (transformation_h) _handle;
98
99         return _convert_image_util_error_code(__func__, err);
100 }
101
102 int image_util_transform_set_hardware_acceleration(transformation_h handle, bool mode)
103 {
104         int err = MM_UTIL_ERROR_NONE;
105         transformation_s *_handle = (transformation_s *) handle;
106
107         image_util_debug("Set hardware_acceleration %d", mode);
108
109         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
110 #ifndef ENABLE_HW_ACCELERATION
111         image_util_retvm_if((mode == true), IMAGE_UTIL_ERROR_NOT_SUPPORTED, "hardware acceleration is not supported");
112 #endif
113
114         err = mm_util_set_hardware_acceleration(_handle->image_h, mode);
115         if (err != MM_UTIL_ERROR_NONE) {
116                 image_util_error("Error - Set hardware_acceleration");
117                 return _convert_image_util_error_code(__func__, err);
118         }
119
120         image_util_debug("Set hardware_acceleration %d", mode);
121         _handle->hardware_acceleration = mode;
122
123         return _convert_image_util_error_code(__func__, err);
124 }
125
126 int image_util_transform_set_colorspace(transformation_h handle, image_util_colorspace_e colorspace)
127 {
128         int err = MM_UTIL_ERROR_NONE;
129         transformation_s *_handle = (transformation_s *) handle;
130
131         image_util_debug("Set colorspace_convert_info [%d]", colorspace);
132
133         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
134
135         err = mm_util_set_colorspace_convert(_handle->image_h, colorspace);
136         if (err != MM_UTIL_ERROR_NONE) {
137                 image_util_error("Error - Set colorspace convert");
138                 return _convert_image_util_error_code(__func__, err);
139         }
140
141         _handle->colorspace = colorspace;
142         _handle->set_convert = true;
143
144         return _convert_image_util_error_code(__func__, err);
145 }
146
147 int image_util_transform_set_resolution(transformation_h handle, unsigned int width, unsigned int height)
148 {
149         int err = MM_UTIL_ERROR_NONE;
150         transformation_s *_handle = (transformation_s *) handle;
151
152         image_util_debug("Set resize_info w[%d] h[%d]", width, height);
153
154         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
155         image_util_retvm_if((_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
156         image_util_retvm_if((_image_util_check_resolution(width, height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid resolution");
157
158         err = mm_util_set_resolution(_handle->image_h, width, height);
159         if (err != MM_UTIL_ERROR_NONE) {
160                 image_util_error("Error - Set resolution");
161                 return _convert_image_util_error_code(__func__, err);
162         }
163         _handle->width = width;
164         _handle->height = height;
165         _handle->set_resize = true;
166
167         return _convert_image_util_error_code(__func__, err);
168 }
169
170 int image_util_transform_set_rotation(transformation_h handle, image_util_rotation_e rotation)
171 {
172         int err = MM_UTIL_ERROR_NONE;
173         transformation_s *_handle = (transformation_s *) handle;
174
175         image_util_debug("Set rotate_info [%d]", rotation);
176
177         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
178
179         err = mm_util_set_rotation(_handle->image_h, rotation);
180         if (err != MM_UTIL_ERROR_NONE) {
181                 image_util_error("Error - Set rotation");
182                 return _convert_image_util_error_code(__func__, err);
183         }
184         _handle->rotation = rotation;
185         _handle->set_rotate = true;
186
187         return _convert_image_util_error_code(__func__, err);
188 }
189
190 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)
191 {
192         int err = MM_UTIL_ERROR_NONE;
193         transformation_s *_handle = (transformation_s *) handle;
194         int dest_width;
195         int dest_height;
196
197         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
198         image_util_retvm_if((_handle->set_resize), IMAGE_UTIL_ERROR_INVALID_OPERATION, "Crop and Resize can't do at the same time");
199
200         dest_width = end_x - start_x;
201         dest_height = end_y - start_y;
202
203         image_util_debug("Set crop_info x[%d] y[%d] w[%d] h[%d]", start_x, start_y, dest_width, dest_height);
204
205         image_util_retvm_if((_image_util_check_resolution(dest_width, dest_height) == false), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid dest resolution");
206         err = mm_util_set_crop_area(_handle->image_h, start_x, start_y, end_x, end_y);
207         if (err != MM_UTIL_ERROR_NONE) {
208                 image_util_error("Error - Set crop area");
209                 return _convert_image_util_error_code(__func__, err);
210         }
211         _handle->start_x = start_x;
212         _handle->start_y = start_y;
213         _handle->end_x = end_x;
214         _handle->end_y = end_y;
215         _handle->set_crop = true;
216
217         return _convert_image_util_error_code(__func__, err);
218 }
219
220 int image_util_transform_get_colorspace(transformation_h handle, image_util_colorspace_e * colorspace)
221 {
222         int ret = IMAGE_UTIL_ERROR_NONE;
223         transformation_s *_handle = (transformation_s *) handle;
224
225         if (_handle == NULL) {
226                 image_util_error("Invalid Handle");
227                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
228         }
229
230         if (!colorspace) {
231                 image_util_error("colorspace area parameter error");
232                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
233         }
234
235         if (!_handle->set_convert) {
236                 image_util_error("Did not set colorspace before");
237                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
238         }
239
240         image_util_debug("Get colorspace_convert_info [%d]", _handle->colorspace);
241
242         *colorspace = _handle->colorspace;
243
244         return ret;
245 }
246
247 int image_util_transform_get_resolution(transformation_h handle, unsigned int *width, unsigned int *height)
248 {
249         int ret = IMAGE_UTIL_ERROR_NONE;
250         transformation_s *_handle = (transformation_s *) handle;
251
252         if (_handle == NULL) {
253                 image_util_error("Invalid Handle");
254                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
255         }
256
257         if (!width || !height) {
258                 image_util_error("resolution area parameter error");
259                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
260         }
261
262         if (!_handle->set_resize) {
263                 image_util_error("Did not set resolution before");
264                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
265         }
266
267         image_util_debug("Get resize_info w[%ui] h[%ui]", _handle->width, _handle->height);
268
269         *width = _handle->width;
270         *height = _handle->height;
271
272         return ret;
273 }
274
275 int image_util_transform_get_rotation(transformation_h handle, image_util_rotation_e * rotation)
276 {
277         int ret = IMAGE_UTIL_ERROR_NONE;
278         transformation_s *_handle = (transformation_s *) handle;
279
280         if (_handle == NULL) {
281                 image_util_error("Invalid Handle");
282                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
283         }
284
285         if (!rotation) {
286                 image_util_error("rotation area parameter error");
287                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
288         }
289
290         if (!_handle->set_rotate) {
291                 image_util_error("Did not set rotation before");
292                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
293         }
294
295         image_util_debug("Get rotate_info [%d]", _handle->rotation);
296
297         *rotation = _handle->rotation;
298
299         return ret;
300 }
301
302 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)
303 {
304         int ret = IMAGE_UTIL_ERROR_NONE;
305         transformation_s *_handle = (transformation_s *) handle;
306
307         if (_handle == NULL) {
308                 image_util_error("Invalid Handle");
309                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
310         }
311
312         if (!start_x || !start_y || !end_x || !end_y) {
313                 image_util_error("crop area parameter error");
314                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
315         }
316
317         if (!_handle->set_crop) {
318                 image_util_error("Did not set crop area before");
319                 return IMAGE_UTIL_ERROR_INVALID_OPERATION;
320         }
321
322         *start_x = _handle->start_x;
323         *start_y = _handle->start_y;
324         *end_x = _handle->end_x;
325         *end_y = _handle->end_y;
326
327         return ret;
328 }
329
330 int image_util_transform_run(transformation_h handle, media_packet_h src, image_util_transform_completed_cb completed_cb, void *user_data)
331 {
332         int err = MM_UTIL_ERROR_NONE;
333         transformation_s *_handle = (transformation_s *) handle;
334
335         image_util_debug("image_util_transform");
336
337         image_util_retvm_if((_handle == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid Handle");
338         image_util_retvm_if((completed_cb == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid callback");
339         image_util_retvm_if((src == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid source");
340         image_util_retvm_if((!_handle->set_convert && !_handle->set_resize && !_handle->set_rotate && !_handle->set_crop), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid transform");
341
342         if (_handle->_util_cb != NULL) {
343                 IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
344                 _handle->_util_cb = NULL;
345         }
346         _handle->_util_cb = (image_util_cb_s *) calloc(1, sizeof(image_util_cb_s));
347         image_util_retvm_if((_handle->_util_cb == NULL), IMAGE_UTIL_ERROR_OUT_OF_MEMORY, "Out of memory");
348
349         _handle->_util_cb->user_data = user_data;
350         _handle->_util_cb->image_processing_completed_cb = completed_cb;
351
352         if (_handle->_util_cb)
353                 err = mm_util_transform(_handle->image_h, src, (mm_util_completed_callback) _image_util_transform_completed_cb, (void *)_handle->_util_cb);
354
355         return _convert_image_util_error_code(__func__, err);
356 }
357
358 int image_util_transform_destroy(transformation_h handle)
359 {
360         int err = MM_UTIL_ERROR_NONE;
361         transformation_s *_handle = (transformation_s *) handle;
362
363         image_util_debug("image_util_destroy");
364
365         if (_handle == NULL) {
366                 image_util_error("Invalid Handle");
367                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
368         }
369
370         err = mm_util_destroy(_handle->image_h);
371
372         IMAGE_UTIL_SAFE_FREE(_handle->_util_cb);
373         IMAGE_UTIL_SAFE_FREE(_handle);
374
375         return _convert_image_util_error_code(__func__, err);
376 }
377
378 int image_util_calculate_buffer_size(int width, int height, image_util_colorspace_e colorspace, unsigned int *size)
379 {
380         int err = MM_UTIL_ERROR_NONE;
381
382         image_util_retvm_if((is_valid_colorspace(colorspace) == FALSE), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid colorspace");
383         image_util_retvm_if((width <= 0 || height <= 0), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "Invalid width or Invalid height");
384         image_util_retvm_if((size == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "size is null");
385
386         err = mm_util_get_image_size(TYPECAST_COLOR(colorspace), width, height, size);
387         return _convert_image_util_error_code(__func__, err);
388 }
389
390 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)
391 {
392         int ret = MM_UTIL_ERROR_NONE;
393
394         image_util_retvm_if((image_buffer == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "image_buffer     is null");
395
396         GModule *module = NULL;
397         ModuleFunc mmutil_imgcv_module_func = NULL;
398         module = g_module_open(PATH_MMUTIL_IMGCV_LIB, G_MODULE_BIND_LAZY);
399         image_util_retvm_if((module == NULL), IMAGE_UTIL_ERROR_NO_SUCH_FILE, "fail to open module");
400
401         g_module_symbol(module, IMGCV_FUNC_NAME, (gpointer *)&mmutil_imgcv_module_func);
402         if (!mmutil_imgcv_module_func)
403                 g_module_close(module);
404
405         image_util_retvm_if((mmutil_imgcv_module_func == NULL), IMAGE_UTIL_ERROR_INVALID_OPERATION, "fail to get symbol");
406
407         unsigned char r_color, g_color, b_color;
408         ret = mmutil_imgcv_module_func((void *)image_buffer, width, height, &r_color, &g_color, &b_color);
409
410         *rgb_r = r_color;
411         *rgb_g = g_color;
412         *rgb_b = b_color;
413
414         if (module) {
415                 g_module_close(module);
416                 module = NULL;
417         }
418
419         return _convert_image_util_error_code(__func__, ret);
420 }
421
422 int image_util_foreach_supported_colorspace(image_util_type_e image_type, image_util_supported_colorspace_cb callback, void *user_data)
423 {
424         int idx = 0;
425
426         image_util_retvm_if((callback == NULL), IMAGE_UTIL_ERROR_INVALID_PARAMETER, "callback is null");
427
428         if ((image_type == IMAGE_UTIL_JPEG) || (image_type == IMAGE_UTIL_PNG)
429                 || (image_type == IMAGE_UTIL_GIF) || (image_type == IMAGE_UTIL_BMP)) {
430                 for (idx = (int)(NUM_OF_COLORSPACE - 1); idx >= 0; idx--) {
431                         if (is_supported_colorspace(idx, image_type))
432                                 if (false == callback(idx, user_data))
433                                         return IMAGE_UTIL_ERROR_NONE;
434
435                 }
436         } else {
437                 return IMAGE_UTIL_ERROR_INVALID_PARAMETER;
438         }
439
440         return IMAGE_UTIL_ERROR_NONE;
441 }