bc02e48ec2008811fad6a5ecf0fa4aa874bf217c
[platform/core/api/media-content.git] / src / media_face.c
1 /*
2 * Copyright (c) 2014 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
18 #include <media_info_private.h>
19
20 #define MAX_SIZE 16
21
22 static int __media_face_check_media_id(const char *media_id)
23 {
24         int ret = MEDIA_CONTENT_ERROR_NONE;
25         char *query_str = NULL;
26         sqlite3_stmt *stmt = NULL;
27         int item_count = 0;
28
29         media_content_retvm_if(!STRING_VALID(media_id), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid media_id");
30
31         /* Get image count */
32         query_str = sqlite3_mprintf(SELECT_IMAGE_COUNT_FROM_MEDIA_BY_ID, media_id);
33         ret = _content_get_result(query_str, &stmt);
34         SQLITE3_SAFE_FREE(query_str);
35         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
36
37         if (sqlite3_step(stmt) == SQLITE_ROW)
38                 item_count = (int)sqlite3_column_int(stmt, 0);
39
40         SQLITE3_FINALIZE(stmt);
41
42         media_content_retvm_if(item_count == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid media_id");
43
44         return MEDIA_CONTENT_ERROR_NONE;
45 }
46
47 int media_face_destroy(media_face_h face)
48 {
49         media_face_s *_face = (media_face_s*)face;
50
51         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
52
53         SAFE_FREE(_face->media_id);
54         SAFE_FREE(_face->face_tag);
55         SAFE_FREE(_face);
56
57         return MEDIA_CONTENT_ERROR_NONE;
58 }
59
60 int media_face_clone(media_face_h *dst, media_face_h src)
61 {
62         media_face_s *_src = (media_face_s*)src;
63
64         media_content_retvm_if(src == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid src handle");
65
66         media_face_s *_dst = (media_face_s *)calloc(1, sizeof(media_face_s));
67         media_content_retvm_if(_dst == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY");
68
69         if (STRING_VALID(_src->media_id)) {
70                 _dst->media_id = strdup(_src->media_id);
71                 if (_dst->media_id == NULL) {
72                         media_face_destroy((media_face_h)_dst);
73                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
74                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
75                 }
76         }
77
78         _dst->face_id = _src->face_id;
79         _dst->face_rect_x = _src->face_rect_x;
80         _dst->face_rect_y = _src->face_rect_y;
81         _dst->face_rect_w = _src->face_rect_w;
82         _dst->face_rect_h = _src->face_rect_h;
83         _dst->orientation = _src->orientation;
84
85         if (STRING_VALID(_src->face_tag)) {
86                 _dst->face_tag = strdup(_src->face_tag);
87                 if (_dst->face_tag == NULL) {
88                         media_face_destroy((media_face_h)_dst);
89                         media_content_error("OUT_OF_MEMORY(0x%08x)", MEDIA_CONTENT_ERROR_OUT_OF_MEMORY);
90                         return MEDIA_CONTENT_ERROR_OUT_OF_MEMORY;
91                 }
92         }
93
94         *dst = (media_face_h)_dst;
95
96         return MEDIA_CONTENT_ERROR_NONE;
97 }
98
99 static void __media_face_convert_itoa(int face_id, char **face_strid)
100 {
101         char buf[MAX_SIZE] = {0, };
102
103         snprintf(buf, MAX_SIZE, "%d", face_id);
104         *face_strid = strndup(buf, strlen(buf));
105 }
106
107 int media_face_get_face_id(media_face_h face, char **face_id)
108 {
109         media_face_s* _face = (media_face_s*)face;
110
111         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
112
113         if (_face->face_id > 0) {
114                 __media_face_convert_itoa(_face->face_id, face_id);
115                 media_content_retvm_if(*face_id == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "Out of memory");
116         } else {
117                 *face_id = NULL;
118         }
119
120         return MEDIA_CONTENT_ERROR_NONE;
121 }
122
123 int media_face_get_media_id(media_face_h face, char **media_id)
124 {
125         media_face_s* _face = (media_face_s*)face;
126
127         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
128
129         if (STRING_VALID(_face->media_id)) {
130                 *media_id = strdup(_face->media_id);
131                 media_content_retvm_if(*media_id == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "Out of memory");
132         } else {
133                 *media_id = NULL;
134         }
135
136         return MEDIA_CONTENT_ERROR_NONE;
137 }
138
139 int media_face_get_face_rect(media_face_h face, unsigned int *rect_x, unsigned int *rect_y, unsigned int *rect_w, unsigned int *rect_h)
140 {
141         media_face_s* _face = (media_face_s*)face;
142
143         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
144         media_content_retvm_if(!(rect_x && rect_y && rect_w && rect_h), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid rect");
145
146         *rect_x = _face->face_rect_x;
147         *rect_y = _face->face_rect_y;
148         *rect_w = _face->face_rect_w;
149         *rect_h = _face->face_rect_h;
150
151         return MEDIA_CONTENT_ERROR_NONE;
152 }
153
154 int media_face_get_orientation(media_face_h face, media_content_orientation_e *orientation)
155 {
156         media_face_s* _face = (media_face_s*)face;
157
158         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
159         media_content_retvm_if(orientation == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid orientation");
160
161         *orientation = _face->orientation;
162
163         return MEDIA_CONTENT_ERROR_NONE;
164 }
165
166 int media_face_get_tag(media_face_h face, char **tag)
167 {
168         media_face_s* _face = (media_face_s*)face;
169
170         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
171
172         if (STRING_VALID(_face->face_tag)) {
173                 *tag = strdup(_face->face_tag);
174                 media_content_retvm_if(*tag == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "Out of memory");
175         } else {
176                 *tag = NULL;
177         }
178
179         return MEDIA_CONTENT_ERROR_NONE;
180 }
181
182 int media_face_create(const char *media_id, media_face_h *face)
183 {
184         int ret = MEDIA_CONTENT_ERROR_NONE;
185
186         media_content_retvm_if(!STRING_VALID(media_id), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid media_id");
187         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
188
189         ret = __media_face_check_media_id(media_id);
190         media_content_retvm_if(ret != MEDIA_CONTENT_ERROR_NONE, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "media_id does not exist or is not an image");
191
192         media_face_s* _face = calloc(1, sizeof(media_face_s));
193         media_content_retvm_if(_face == NULL, MEDIA_CONTENT_ERROR_OUT_OF_MEMORY, "Out of memory");
194
195         _face->media_id = strdup(media_id);
196
197         *face = (media_face_h)_face;
198
199         return MEDIA_CONTENT_ERROR_NONE;
200 }
201
202 int media_face_set_face_rect(media_face_h face, unsigned int rect_x, unsigned int rect_y, unsigned int rect_w, unsigned int rect_h)
203 {
204         media_face_s* _face = (media_face_s*)face;
205
206         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
207         media_content_retvm_if(rect_w == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid rect_w");
208         media_content_retvm_if(rect_h == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid rect_h");
209
210         _face->face_rect_x = rect_x;
211         _face->face_rect_y = rect_y;
212         _face->face_rect_w = rect_w;
213         _face->face_rect_h = rect_h;
214
215         return MEDIA_CONTENT_ERROR_NONE;
216 }
217
218 int media_face_set_orientation(media_face_h face, media_content_orientation_e orientation)
219 {
220         media_face_s* _face = (media_face_s*)face;
221
222         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
223
224         _face->orientation = orientation;
225
226         return MEDIA_CONTENT_ERROR_NONE;
227 }
228
229 int media_face_set_tag(media_face_h face, const char *tag)
230 {
231         media_face_s* _face = (media_face_s*)face;
232
233         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
234
235         if (STRING_VALID(tag))
236                 _face->face_tag = strdup(tag);
237         else
238                 _face->face_tag = NULL;
239
240         return MEDIA_CONTENT_ERROR_NONE;
241 }
242
243 int media_face_insert_to_db(media_face_h face)
244 {
245         int ret = MEDIA_CONTENT_ERROR_NONE;
246         char *query_str = NULL;
247         sqlite3_stmt *stmt = NULL;
248
249         media_face_s* _face = (media_face_s*)face;
250
251         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
252         media_content_retvm_if(_face->media_id == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid media_id");
253         media_content_retvm_if(_face->face_rect_w == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid rect_w");
254         media_content_retvm_if(_face->face_rect_h == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid rect_h");
255
256         query_str = sqlite3_mprintf(INSERT_FACE_TO_FACE, _face->media_id, _face->face_rect_x, _face->face_rect_y, _face->face_rect_w, _face->face_rect_h, _face->orientation, _face->face_tag);
257
258         ret = _content_query_sql(query_str);
259         SQLITE3_SAFE_FREE(query_str);
260
261         query_str = sqlite3_mprintf(SELECT_FACE_ID, _face->media_id, _face->face_rect_x, _face->face_rect_y, _face->face_rect_w, _face->face_rect_h, _face->orientation);
262         ret = _content_get_result(query_str, &stmt);
263         SQLITE3_SAFE_FREE(query_str);
264         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
265
266         if (sqlite3_step(stmt) == SQLITE_ROW)
267                 _face->face_id = (int)sqlite3_column_int(stmt, 0);
268
269         SQLITE3_FINALIZE(stmt);
270
271
272         return ret;
273 }
274
275 int media_face_update_to_db(media_face_h face)
276 {
277         int ret = MEDIA_CONTENT_ERROR_NONE;
278         char *query_str = NULL;
279
280         media_face_s* _face = (media_face_s*)face;
281
282         media_content_retvm_if(face == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid handle");
283         media_content_retvm_if(_face->face_id == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid face_id");
284         media_content_retvm_if(_face->media_id == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid media_id");
285         media_content_retvm_if(_face->face_rect_w == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid rect_w");
286         media_content_retvm_if(_face->face_rect_h == 0, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "Invalid rect_h");
287
288         query_str = sqlite3_mprintf(UPDATE_FACE_TO_FACE, _face->face_rect_x, _face->face_rect_y, _face->face_rect_w, _face->face_rect_h, _face->orientation, _face->face_tag, _face->face_id);
289
290         ret = _content_query_sql(query_str);
291         SQLITE3_SAFE_FREE(query_str);
292
293         return ret;
294 }
295
296 static int __media_face_safe_atoi(const char *buffer, int *si)
297 {
298         char *end = NULL;
299         errno = 0;
300         media_content_retvm_if(buffer == NULL || si == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid parameter");
301
302         const long sl = strtol(buffer, &end, 10);
303
304         media_content_retvm_if(end == buffer, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "not a decimal number");
305         media_content_retvm_if('\0' != *end, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "extra characters at end of input: %s", end);
306         media_content_retvm_if((LONG_MIN == sl || LONG_MAX == sl) && (ERANGE == errno), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "out of range of type long");
307         media_content_retvm_if(sl > INT_MAX, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "greater than INT_MAX");
308         media_content_retvm_if(sl < INT_MIN, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "less than INT_MIN");
309
310         *si = (int)sl;
311
312         return MEDIA_CONTENT_ERROR_NONE;
313 }
314
315 int media_face_delete_from_db(const char *face_id)
316 {
317         int ret = MEDIA_CONTENT_ERROR_NONE;
318         char *query_str = NULL;
319         int query_face_id = 0;
320         media_content_retvm_if(!STRING_VALID(face_id), MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid face_id");
321
322         ret = __media_face_safe_atoi(face_id, &query_face_id);
323         media_content_retvm_if(ret != MEDIA_CONTENT_ERROR_NONE, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid face_id");
324
325         /*Update modified_time to 0.. It will restore the deleted face when media_info_start_face_detection() is called */
326         query_str = sqlite3_mprintf(UPDATE_MEDIA_INFO_IN_FACE_SCAN_LIST, query_face_id);
327         ret = _content_query_sql(query_str);
328         SQLITE3_SAFE_FREE(query_str);
329         media_content_retv_if(ret != MEDIA_CONTENT_ERROR_NONE, ret);
330
331         query_str = sqlite3_mprintf(DELETE_FACE_FROM_FACE, query_face_id);
332         ret = _content_query_sql(query_str);
333         SQLITE3_SAFE_FREE(query_str);
334
335         return ret;
336 }
337
338 int media_face_get_face_count_from_db(filter_h filter, int *face_count)
339 {
340         int ret = MEDIA_CONTENT_ERROR_NONE;
341
342         if (face_count == NULL) {
343                 media_content_error("INVALID_PARAMETER(0x%08x)", MEDIA_CONTENT_ERROR_INVALID_PARAMETER);
344                 return MEDIA_CONTENT_ERROR_INVALID_PARAMETER;
345         }
346
347         ret = _media_db_get_group_count(filter, MEDIA_GROUP_FACE, face_count);
348
349         return ret;
350 }
351
352 int media_face_foreach_face_from_db(filter_h filter, media_face_cb callback, void *user_data)
353 {
354         int ret = MEDIA_CONTENT_ERROR_NONE;
355
356         media_content_retvm_if(callback == NULL, MEDIA_CONTENT_ERROR_INVALID_PARAMETER, "invalid paramter");
357
358         ret = _media_db_get_face(NULL, filter, callback, user_data);
359
360         return ret;
361 }