[content] Remove Open Service Platform words
[platform/framework/native/content.git] / src / FCnt_ContentManagerUtilImpl.cpp
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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  * @file                FCnt_ContentManagerUtilImpl.cpp
18  * @brief               This is the implementation file for the %_ContentManagerUtilImpl class.
19  *
20  * This file contains implementation of the %_ContentManagerUtilImpl class.
21  */
22
23 #include <stdlib.h>
24 #include <mime_type.h>
25 #include <FBaseSysLog.h>
26 #include <FBaseByteBuffer.h>
27 #include <FIoDirectory.h>
28 #include <FAppApp.h>
29 #include <FSysEnvironment.h>
30 #include <FMediaImage.h>
31 #include <FMediaImageBuffer.h>
32 #include <FMediaImageUtil.h>
33 #include <FCntImageMetadata.h>
34 #include <FCntAudioMetadata.h>
35 #include <FCntVideoMetadata.h>
36 #include <FCnt_ContentManagerUtilImpl.h>
37 #include <FCnt_AudioMetadataImpl.h>
38 #include <FCnt_VideoMetadataImpl.h>
39 #include <FCnt_ImageMetadataImpl.h>
40 #include <FBase_StringConverter.h>
41 #include <FIo_FileImpl.h>
42 #include <FGrp_BitmapImpl.h>
43 #include <FMedia_ImageDecoder.h>
44 #include <FMedia_ImageImpl.h>
45 #include <FApp_AppInfo.h>
46
47 using namespace Tizen::Base;
48 using namespace Tizen::Io;
49 using namespace Tizen::Media;
50 using namespace Tizen::Graphics;
51 using namespace Tizen::App;
52 using namespace Tizen::System;
53 using namespace std;
54
55 namespace Tizen { namespace Content
56 {
57 // Types of content, format supported and default values
58 static const int IMAGE_BUFF_LENGTH = 100;
59 static const int THUMBNAIL_IMAGE_WIDTH = 80;
60 static const int THUMBNAIL_IMAGE_HEIGHT = 60;
61 static const int MINUTES = 60;
62 static const int SECONDS = 3600;
63
64 //
65 // E_SUCCESS
66 // E_INVALID_ARG
67 // E_OUT_OF_MEMORY
68 //
69 ImageMetadata*
70 _ContentManagerUtilImpl::GetImageMetaN(const String& contentPath, bool internal)
71 {
72         ClearLastResult();
73
74         if (!internal)
75         {
76                 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
77                                 "[E_INVALID_ARG] The path is not compatible.");
78         }
79         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
80                         "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
81
82         // create object here as it needs to be passed to client in any case to make sure Get APIs do not crash
83         unique_ptr<ImageMetadata> pImageMetadata(new (nothrow) ImageMetadata());
84         SysTryReturn(NID_CNT, pImageMetadata != null, null, E_OUT_OF_MEMORY,
85                         "[E_OUT_OF_MEMORY] pImageMetadata is null.");
86
87         _ImageMetadataImpl* pImageMetaImpl = _ImageMetadataImpl::GetInstance(*(pImageMetadata.get()));
88         SysTryReturn(NID_CNT, pImageMetaImpl != null, null, E_OUT_OF_MEMORY,
89                         "[E_OUT_OF_MEMORY] pImageMetaImpl is null.");
90
91         ImageMeta* pMetadata = pImageMetaImpl->GetImageMetadata();
92         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
93                         "[E_INVALID_ARG] pMetadata is null.");
94
95         //assign by default here and overwrite below if width and height presents in EXIF data.
96         ImageFormat imgType = IMG_FORMAT_NONE;
97         Dimension dim(0,0);
98
99         result r = _ImageImpl::GetImageInfo(contentPath, imgType, dim);
100         SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_INVALID_ARG,
101                         "[E_INVALID_ARG] GetImageInfo failed.");
102
103         pMetadata->width = dim.width;
104         pMetadata->height = dim.height;
105         pMetadata->contentPath = contentPath;
106
107         if (imgType == IMG_FORMAT_JPG)
108         {
109                 unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
110                 SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
111                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
112
113                 unique_ptr<ExifData, ExifDataDeleter> pExifdata(exif_data_new_from_file(pFileName.get()));
114                 if (pExifdata != null)
115                 {
116                         ExifTag tag;
117                         ExifByteOrder byteOrder;
118                         ExifEntry** pEntries = null;
119                         const char* pData = null;
120                         char buf[IMAGE_BUFF_LENGTH] = {0, };
121                         char mmBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store minutes value of GPS data
122                         char ssBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store seconds value of GPS data
123                         ExifContent* pExifcont[EXIF_IFD_COUNT];
124                         int index = 0;
125                         char latitudeRef = 0; // to store latitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
126                         char longitudeRef = 0; // to store longitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
127                         unsigned int entryCount = 0;
128
129                         for (int i = 0; i < EXIF_IFD_COUNT; i++)
130                         {
131                                 pExifcont[i] = pExifdata->ifd[i];
132                                 entryCount = pExifcont[i]->count;
133                                 pEntries = pExifcont[i]->entries;
134                                 for (unsigned int j = 0; j < entryCount; j++)
135                                 {
136                                         tag = pEntries[j]->tag;
137                                         pData = exif_entry_get_value(pEntries[j], buf, sizeof(buf));
138                                         SysTryReturn(NID_CNT, pData != null, pImageMetadata.release(), E_INVALID_ARG,
139                                                         "[E_INVALID_ARG] exif_entry_get_value failed.");
140
141                                         if (tag == EXIF_TAG_PIXEL_X_DIMENSION)
142                                         {
143                                                 pMetadata->width = atoi(buf);
144                                         }
145                                         else if (tag == EXIF_TAG_PIXEL_Y_DIMENSION)
146                                         {
147                                                 pMetadata->height = atoi(buf);
148                                         }
149                                         else if (tag == EXIF_TAG_MAKE)
150                                         {
151                                                 pMetadata->pManufacturer = new (nothrow) String(buf);
152                                                 SysTryReturn(NID_CNT, pMetadata->pManufacturer != null, null, E_OUT_OF_MEMORY,
153                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
154                                         }
155                                         else if (tag == EXIF_TAG_MODEL)
156                                         {
157                                                 pMetadata->pModel = new (nothrow) String(buf);
158                                                 SysTryReturn(NID_CNT, pMetadata->pModel != null, null, E_OUT_OF_MEMORY,
159                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
160                                         }
161                                         else if (tag == EXIF_TAG_DATE_TIME)
162                                         {
163                                                 pMetadata->pDateTime = new (nothrow) String(buf);
164                                                 SysTryReturn(NID_CNT, pMetadata->pDateTime != null, null, E_OUT_OF_MEMORY,
165                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
166                                         }
167                                         else if (tag == EXIF_TAG_ORIENTATION)
168                                         {
169                                                 //get the byte order(little endian or big endian) before extracting orientation type
170                                                 byteOrder = exif_data_get_byte_order(pEntries[j]->parent->parent);
171                                                 pMetadata->orientation = static_cast<ImageOrientationType>(exif_get_short(pEntries[j]->data, byteOrder));
172                                         }
173                                         else if (tag == EXIF_TAG_SOFTWARE)
174                                         {
175                                                 pMetadata->pSoftware = new (nothrow) String(buf);
176                                                 SysTryReturn(NID_CNT, pMetadata->pSoftware != null, null, E_OUT_OF_MEMORY,
177                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
178                                         }
179                                         else if (tag == EXIF_TAG_GPS_LATITUDE_REF)
180                                         {
181                                                 latitudeRef = buf[0]; // GPS Latitude reference value will be 'N'(NORTH) or 'S'(SOUTH)
182                                         }
183                                         else if (tag == EXIF_TAG_GPS_LATITUDE)
184                                         {
185                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
186                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
187                                                 {
188                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
189                                                 }
190                                                 index = 0; //re-assign index value as this is new buffer
191                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
192                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
193                                                 {
194                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
195                                                 }
196
197                                                 char *pLocal;
198                                                 std::unique_ptr<char> pCurrentLocal(null);
199                                                 pLocal = setlocale (LC_ALL, 0); // Get the name of the current locale.
200                                                 if( pLocal == null )
201                                                 {
202                                                         SysLog(NID_CNT, "setlocale failed. (get current locale)");
203                                                         continue;
204                                                 }
205                                                 pCurrentLocal.reset(strdup (pLocal));
206
207                                                 pLocal = setlocale(LC_ALL, "C");
208                                                 if( pLocal == null )
209                                                 {
210                                                         SysLog(NID_CNT, "setlocale failed. (set POSIX C locale)");
211                                                         continue;
212                                                 }
213
214                                                 double ddVal = atof(buf); // degree value
215                                                 double mmVal = atof(mmBuff); // minutesvalue
216                                                 double ssVal = atof(ssBuff); // seconds value
217
218                                                 pLocal = setlocale (LC_ALL, pCurrentLocal.get()); // restore the locale.
219                                                 if( pLocal == null )
220                                                 {
221                                                         SysLog(NID_CNT, "setlocale failed. (set current locale)");
222                                                         continue;
223                                                 }
224
225                                                 pMetadata->latitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
226
227                                                 // if latitude designation is Southern (SOUTH) then latitude degree will be negative DD
228                                                 if (latitudeRef == 'S')
229                                                 {
230                                                         pMetadata->latitude = (pMetadata->latitude * (double)(-1));
231                                                 }
232                                         }
233                                         else if (tag == EXIF_TAG_GPS_LONGITUDE_REF)
234                                         {
235                                                 longitudeRef = buf[0]; // GPS Longitude reference value will be 'W'(WEST) or 'E'(EAST)
236                                         }
237                                         else if (tag == EXIF_TAG_GPS_LONGITUDE)
238                                         {
239                                                 index = 0; //re-assign index value as this is new buffer
240                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
241                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
242                                                 {
243                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
244                                                 }
245                                                 index = 0; //re-assign index value as this is new buffer
246                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
247                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
248                                                 {
249                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
250                                                 }
251
252                                                 char *pLocal;
253                                                 std::unique_ptr<char> pCurrentLocal(null);
254                                                 pLocal = setlocale (LC_ALL, 0); // Get the name of the current locale.
255                                                 if( pLocal == null )
256                                                 {
257                                                         SysLog(NID_CNT, "setlocale failed. (get current locale)");
258                                                         continue;
259                                                 }
260                                                 pCurrentLocal.reset(strdup (pLocal));
261
262                                                 pLocal = setlocale(LC_ALL, "C");
263                                                 if( pLocal == null )
264                                                 {
265                                                         SysLog(NID_CNT, "setlocale failed. (set POSIX C locale)");
266                                                         continue;
267                                                 }
268
269                                                 double ddVal = atof(buf); // degree value
270                                                 double mmVal = atof(mmBuff); // minutesvalue
271                                                 double ssVal = atof(ssBuff); // seconds value
272
273                                                 pLocal = setlocale (LC_ALL, pCurrentLocal.get()); // restore the locale.
274                                                 if( pLocal == null )
275                                                 {
276                                                         SysLog(NID_CNT, "setlocale failed. (set current locale)");
277                                                         continue;
278                                                 }
279
280                                                 pMetadata->longitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
281
282                                                 // if longitude designation is Western (WEST) then longitude degree will be negative DD
283                                                 if (longitudeRef == 'W')
284                                                 {
285                                                         pMetadata->longitude = (pMetadata->longitude * (double)(-1));
286                                                 }
287                                         }
288                                         else if (tag == EXIF_TAG_WHITE_BALANCE)
289                                         {
290                                                 pMetadata->pWhiteBalance = new (nothrow) String(buf);
291                                                 SysTryReturn(NID_CNT, pMetadata->pWhiteBalance != null, null, E_OUT_OF_MEMORY,
292                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
293                                         }
294                                 }
295                         }
296                 }
297         }
298
299         return pImageMetadata.release();
300 }
301
302 void
303 _ContentManagerUtilImpl::ParseBuffer(char* pBuffer, int& count)
304 {
305         if ((*pBuffer != ',') && (*pBuffer != '\0')) // parse the buffer till ',' or '\0' and return the index
306         {
307                 ParseBuffer(++pBuffer, ++count);
308         }
309 }
310
311 //
312 // E_SUCCESS
313 // E_INVALID_ARG
314 // E_OUT_OF_MEMORY
315 //
316 AudioMetadata*
317 _ContentManagerUtilImpl::GetAudioMetaN(const String& contentPath)
318 {
319         ClearLastResult();
320
321         SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
322                         "[E_INVALID_ARG] The path is not compatible.");
323         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
324                         "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
325
326         // create here to make sure that get apis will not crash though the below API calls fails in case of invalid file.
327         unique_ptr<AudioMetadata> pAudioMetadata(new (nothrow) AudioMetadata());
328         SysTryReturn(NID_CNT, pAudioMetadata != null, null, E_OUT_OF_MEMORY,
329                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
330
331         _AudioMetadataImpl* pAudioMetaImpl = _AudioMetadataImpl::GetInstance(*(pAudioMetadata.get()));
332         SysTryReturn(NID_CNT, pAudioMetaImpl != null, null, E_OUT_OF_MEMORY,
333                         "[E_OUT_OF_MEMORY] pAudioMetaImpl is null.");
334
335         AudioMeta* pMetadata = pAudioMetaImpl->GetAudioMetadata();
336         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
337                         "[E_INVALID_ARG] pMetadata is null.");
338
339         pMetadata->contentPath = contentPath;
340
341         // Create the metadata extractor handle
342         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
343         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
344                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
345
346         int retVal = metadata_extractor_create(pExtractor.get());
347         result r = ErrorMapToRetVal(retVal);
348         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
349                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
350
351         // Set file path of content to extract the metadata
352         unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
353         SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
354                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
355
356         retVal = metadata_extractor_set_path(*(pExtractor.get()), pFileName.get());
357         r = ErrorMapToRetVal(retVal);
358         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
359                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
360
361         // Get all relavent audio metadata by passing relavent attirbutes
362         char* __pAudioMeta = null;
363         unique_ptr<char, CharDeleter> pAudioMeta(null);
364
365         // bitrate
366         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pAudioMeta);
367         if (__pAudioMeta != null)
368         {
369                 pAudioMeta.reset(__pAudioMeta);
370                 pMetadata->bitrate = atoi(pAudioMeta.get());
371         }
372         else
373         {
374                 r = ErrorMapToRetVal(retVal);
375                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
376                                 "[%s] metadata_extractor_get_metadata(bitrate) failed.", GetErrorMessage(r));
377         }
378
379         // channelcount
380         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_CHANNELS, &__pAudioMeta);
381         if (__pAudioMeta != null)
382         {
383                 pAudioMeta.reset(__pAudioMeta);
384                 pMetadata->channelCount = atoi(pAudioMeta.get());
385         }
386         else
387         {
388                 r = ErrorMapToRetVal(retVal);
389                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
390                                 "[%s] metadata_extractor_get_metadata(channels) failed.", GetErrorMessage(r));
391         }
392
393         // duration
394         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pAudioMeta);
395         if (__pAudioMeta != null)
396         {
397                 pAudioMeta.reset(__pAudioMeta);
398                 pMetadata->duration = atoi(pAudioMeta.get());
399         }
400         else
401         {
402                 r = ErrorMapToRetVal(retVal);
403                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
404                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
405         }
406
407         // frequency
408         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_SAMPLERATE, &__pAudioMeta);
409         if (__pAudioMeta != null)
410         {
411                 pAudioMeta.reset(__pAudioMeta);
412                 pMetadata->frequency = atoi(pAudioMeta.get());
413         }
414         else
415         {
416                 r = ErrorMapToRetVal(retVal);
417                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
418                                 "[%s] metadata_extractor_get_metadata(frequency) failed.", GetErrorMessage(r));
419         }
420
421         // albumname
422         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ALBUM, &__pAudioMeta);
423         if (__pAudioMeta != null)
424         {
425                 pAudioMeta.reset(__pAudioMeta);
426                 pMetadata->pAlbumName = new (nothrow) String(pAudioMeta.get());
427                 SysTryReturn(NID_CNT, pMetadata->pAlbumName != null, null, E_OUT_OF_MEMORY,
428                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
429         }
430         else
431         {
432                 r = ErrorMapToRetVal(retVal);
433                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
434                                 "[%s] metadata_extractor_get_metadata(album name) failed.", GetErrorMessage(r));
435         }
436
437         // artist
438         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ARTIST, &__pAudioMeta);
439         if (pAudioMeta.get() != null)
440         {
441                 pAudioMeta.reset(__pAudioMeta);
442                 pMetadata->pArtist = new (nothrow) String(pAudioMeta.get());
443                 SysTryReturn(NID_CNT, pMetadata->pArtist != null, null, E_OUT_OF_MEMORY,
444                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
445         }
446         else
447         {
448                 r = ErrorMapToRetVal(retVal);
449                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
450                                 "[%s] metadata_extractor_get_metadata(artist) failed.", GetErrorMessage(r));
451         }
452
453         // copyright
454         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COPYRIGHT, &__pAudioMeta);
455         if (__pAudioMeta != null)
456         {
457                 pAudioMeta.reset(__pAudioMeta);
458                 pMetadata->pCopyright = new (nothrow) String(pAudioMeta.get());
459                 SysTryReturn(NID_CNT, pMetadata->pCopyright != null, null, E_OUT_OF_MEMORY,
460                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
461         }
462         else
463         {
464                 r = ErrorMapToRetVal(retVal);
465                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
466                                 "[%s] metadata_extractor_get_metadata(copyright) failed.", GetErrorMessage(r));
467         }
468
469         // genre
470         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pAudioMeta);
471         if (__pAudioMeta != null)
472         {
473                 pAudioMeta.reset(__pAudioMeta);
474                 pMetadata->pGenre = new (nothrow) String(pAudioMeta.get());
475                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
476                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
477         }
478         else
479         {
480                 r = ErrorMapToRetVal(retVal);
481                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
482                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
483         }
484
485         // title
486         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TITLE, &__pAudioMeta);
487         if (__pAudioMeta != null)
488         {
489                 pAudioMeta.reset(__pAudioMeta);
490                 pMetadata->pTitle = new (nothrow) String(pAudioMeta.get());
491                 SysTryReturn(NID_CNT, pMetadata->pTitle != null, null, E_OUT_OF_MEMORY,
492                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
493         }
494         else
495         {
496                 r = ErrorMapToRetVal(retVal);
497                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
498                                 "[%s] metadata_extractor_get_metadata(title) failed.", GetErrorMessage(r));
499         }
500
501         // comment
502         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pAudioMeta);
503         if (__pAudioMeta != null)
504         {
505                 pAudioMeta.reset(__pAudioMeta);
506                 pMetadata->pComment = new (nothrow) String(pAudioMeta.get());
507                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
508                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
509         }
510         else
511         {
512                 r = ErrorMapToRetVal(retVal);
513                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
514                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
515         }
516
517         // description
518         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pAudioMeta);
519         if (__pAudioMeta != null)
520         {
521                 pAudioMeta.reset(__pAudioMeta);
522                 pMetadata->pDescription = new (nothrow) String(pAudioMeta.get());
523                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
524                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
525         }
526         else
527         {
528                 r = ErrorMapToRetVal(retVal);
529                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
530                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
531         }
532
533         // recording date
534         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_RECDATE, &__pAudioMeta);
535         if (__pAudioMeta != null)
536         {
537                 pAudioMeta.reset(__pAudioMeta);
538                 pMetadata->pRecordingDate = new (nothrow) String(pAudioMeta.get());
539                 SysTryReturn(NID_CNT, pMetadata->pRecordingDate != null, null, E_OUT_OF_MEMORY,
540                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
541         }
542         else
543         {
544                 r = ErrorMapToRetVal(retVal);
545                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
546                                 "[%s] metadata_extractor_get_metadata(recording date) failed.", GetErrorMessage(r));
547         }
548
549         // author
550         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUTHOR, &__pAudioMeta);
551         if (__pAudioMeta != null)
552         {
553                 pAudioMeta.reset(__pAudioMeta);
554                 pMetadata->pComposer = new (nothrow) String(pAudioMeta.get());
555                 SysTryReturn(NID_CNT, pMetadata->pComposer != null, null, E_OUT_OF_MEMORY,
556                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
557         }
558         else
559         {
560                 r = ErrorMapToRetVal(retVal);
561                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
562                                 "[%s] metadata_extractor_get_metadata(author) failed.", GetErrorMessage(r));
563         }
564
565         // track info
566         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TRACK_NUM, &__pAudioMeta);
567         if (__pAudioMeta != null)
568         {
569                 pAudioMeta.reset(__pAudioMeta);
570                 pMetadata->pTrackInfo = new (nothrow) String(pAudioMeta.get());
571                 SysTryReturn(NID_CNT, pMetadata->pTrackInfo != null, null, E_OUT_OF_MEMORY,
572                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
573
574                 // if the string contains the track info like track num/track position,
575                 // then track position will be ignored and only track num is returned
576                 // no need to parse this string, since only track number is required
577                 pMetadata->trackNum = atoi(pAudioMeta.get());
578         }
579         else
580         {
581                 r = ErrorMapToRetVal(retVal);
582                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
583                                 "[%s] metadata_extractor_get_metadata(track info) failed.", GetErrorMessage(r));
584         }
585
586         // date
587         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DATE, &__pAudioMeta);
588         if (__pAudioMeta != null)
589         {
590                 pAudioMeta.reset(__pAudioMeta);
591                 pMetadata->year = atoi(pAudioMeta.get());
592         }
593         else
594         {
595                 r = ErrorMapToRetVal(retVal);
596                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
597                                 "[%s] metadata_extractor_get_metadata(date) failed.", GetErrorMessage(r));
598         }
599
600         // artwork
601         int size = 0;
602         void* __pArtwork = null;
603         unique_ptr<void, VoidDeleter> pArtwork(null);
604
605         // Get the artwork image in media file
606         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pAudioMeta);
607
608         //Check if the albumart present and pass it to client if it is successfully processed, otherwise ignore any errors
609         //while processing albumart. This is to pass the other metadata tags to application.
610         if (__pArtwork != null)
611         {
612                 pArtwork.reset(__pArtwork);
613
614                 Image img;
615                 ImageFormat format = IMG_FORMAT_NONE;
616                 ByteBuffer buffer;
617
618                 r = buffer.Construct(size);
619                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
620                 {
621                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
622                         if (!IsFailed(r))
623                         {
624                                 r = img.Construct();
625                                 if (!IsFailed(r))
626                                 {
627                                         format = img.GetImageFormat(buffer);
628                                         pMetadata->pThumbnail = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888,
629                                                                          THUMBNAIL_IMAGE_WIDTH, THUMBNAIL_IMAGE_HEIGHT);
630                                         if (pMetadata->pThumbnail == null)
631                                         {
632                                                 // Because Thumbnail is one of the metadata, it is not exception in this function.
633                                                 SysLog(NID_CNT, "DecodeN failed.");
634                                         }
635                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
636                                         if (pMetadata->pAlbumArt == null)
637                                         {
638                                                 // Because Album Art is one of the metadata, it is not exception in this function.
639                                                 SysLog(NID_CNT, "DecodeN failed.");
640                                         }
641                                 }
642                         }
643                 }
644         }
645         else
646         {
647                 r = ErrorMapToRetVal(retVal);
648                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
649                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
650         }
651
652         return pAudioMetadata.release();
653 }
654
655 //
656 // E_SUCCESS
657 // E_INVALID_ARG
658 // E_OUT_OF_MEMORY
659 //
660 VideoMetadata*
661 _ContentManagerUtilImpl::GetVideoMetaN(const String& contentPath)
662 {
663         ClearLastResult();
664
665         SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
666                         "[E_INVALID_ARG] The path is not compatible.");
667         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
668                         "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
669
670         // need to create here to make sure that all get APIs will not crash in case of corrupted file
671         unique_ptr<VideoMetadata> pVideoMetadata(new (nothrow) VideoMetadata());
672         SysTryReturn(NID_CNT, pVideoMetadata != null, null, E_OUT_OF_MEMORY,
673                         "[E_OUT_OF_MEMORY] The memory insufficient.");
674
675         _VideoMetadataImpl* pVideoMetaImpl = _VideoMetadataImpl::GetInstance(*(pVideoMetadata.get()));
676         SysTryReturn(NID_CNT, pVideoMetaImpl != null, null, E_OUT_OF_MEMORY,
677                         "[E_OUT_OF_MEMORY] pVideoMetaImpl is null.");
678
679         VideoMeta* pMetadata = pVideoMetaImpl->GetVideoMetadata();
680         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
681                         "[E_INVALID_ARG] pMetadata is null.");
682
683         pMetadata->contentPath = contentPath;
684
685         // Create the metadata extractor handle
686         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
687         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
688                                 "[E_OUT_OF_MEMORY] The memory insufficient.");
689
690         int retVal = metadata_extractor_create(pExtractor.get());
691         result r = ErrorMapToRetVal(retVal);
692         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
693                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
694
695         // Set file path of content to extract the metadata
696         unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
697         SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
698                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
699
700         retVal = metadata_extractor_set_path(*(pExtractor.get()), pFileName.get());
701         r = ErrorMapToRetVal(retVal);
702         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
703                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
704
705         // Get all relavent video metadata by passing relavent attirbutes
706         char* __pVideoMeta = null;
707         unique_ptr<char, CharDeleter> pVideoMeta(null);
708
709         // width
710         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_WIDTH, &__pVideoMeta);
711         if (__pVideoMeta != null)
712         {
713                 pVideoMeta.reset(__pVideoMeta);
714                 pMetadata->width = atoi(pVideoMeta.get());
715         }
716         else
717         {
718                 r = ErrorMapToRetVal(retVal);
719                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
720                                 "[%s] metadata_extractor_get_metadata(width) failed.", GetErrorMessage(r));
721         }
722
723         // height
724         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_HEIGHT, &__pVideoMeta);
725         if (__pVideoMeta != null)
726         {
727                 pVideoMeta.reset(__pVideoMeta);
728                 pMetadata->height = atoi(pVideoMeta.get());
729         }
730         else
731         {
732                 r = ErrorMapToRetVal(retVal);
733                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
734                                 "[%s] metadata_extractor_get_metadata(height) failed.", GetErrorMessage(r));
735         }
736
737         // video bitrate
738         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_BITRATE, &__pVideoMeta);
739         if (__pVideoMeta != null)
740         {
741                 pVideoMeta.reset(__pVideoMeta);
742                 pMetadata->videoBitrate = atoi(pVideoMeta.get());
743         }
744         else
745         {
746                 r = ErrorMapToRetVal(retVal);
747                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
748                                 "[%s] metadata_extractor_get_metadata(video bitrate) failed.", GetErrorMessage(r));
749         }
750
751         // audio bitrate
752         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pVideoMeta);
753         if (__pVideoMeta != null)
754         {
755                 pVideoMeta.reset(__pVideoMeta);
756                 pMetadata->audioBitrate = atoi(pVideoMeta.get());
757         }
758         else
759         {
760                 r = ErrorMapToRetVal(retVal);
761                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
762                                 "[%s] metadata_extractor_get_metadata(audio bitrate) failed.", GetErrorMessage(r));
763         }
764
765         // framerate
766         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_FPS, &__pVideoMeta);
767         if (__pVideoMeta != null)
768         {
769                 pVideoMeta.reset(__pVideoMeta);
770                 pMetadata->framerate = atoi(pVideoMeta.get());
771         }
772         else
773         {
774                 r = ErrorMapToRetVal(retVal);
775                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
776                                 "[%s] metadata_extractor_get_metadata(framerate) failed.", GetErrorMessage(r));
777         }
778
779         // duration
780         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pVideoMeta);
781         if (__pVideoMeta != null)
782         {
783                 pVideoMeta.reset(__pVideoMeta);
784                 pMetadata->duration = atoi(pVideoMeta.get());
785         }
786         else
787         {
788                 r = ErrorMapToRetVal(retVal);
789                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
790                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
791         }
792
793         // genre
794         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pVideoMeta);
795         if (__pVideoMeta != null)
796         {
797                 pVideoMeta.reset(__pVideoMeta);
798                 pMetadata->pGenre = new (nothrow) String(pVideoMeta.get()); //allocate memory
799                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
800                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
801         }
802         else
803         {
804                 r = ErrorMapToRetVal(retVal);
805                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
806                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
807         }
808
809         // comment
810         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pVideoMeta);
811         if (__pVideoMeta != null)
812         {
813                 pVideoMeta.reset(__pVideoMeta);
814                 pMetadata->pComment = new (nothrow) String(pVideoMeta.get());
815                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
816                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
817         }
818         else
819         {
820                 r = ErrorMapToRetVal(retVal);
821                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
822                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
823         }
824
825         // description
826         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pVideoMeta);
827         if (__pVideoMeta != null)
828         {
829                 pVideoMeta.reset(__pVideoMeta);
830                 pMetadata->pDescription = new (nothrow) String(pVideoMeta.get());
831                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
832                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
833         }
834         else
835         {
836                 r = ErrorMapToRetVal(retVal);
837                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
838                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
839         }
840
841         // artwork
842         int size = 0;
843         void* __pArtwork = null;
844         unique_ptr<void, VoidDeleter> pArtwork(null);
845
846         // Get the artwork image in media file
847         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pVideoMeta);
848         if (__pArtwork != null)
849         {
850                 pArtwork.reset(__pArtwork);
851
852                 Image img;
853                 ImageFormat format = IMG_FORMAT_NONE;
854                 ByteBuffer buffer;
855
856                 r = buffer.Construct(size);
857                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
858                 {
859                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
860                         if (!IsFailed(r))
861                         {
862                                 r = img.Construct();
863                                 if (!IsFailed(r))
864                                 {
865                                         format = img.GetImageFormat(buffer);
866
867                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
868                                         if (pMetadata->pAlbumArt == null)
869                                         {
870                                                 // Because Album Art is one of the metadata, it is not exception in this function.
871                                                 SysLog(NID_CNT, "DecodeN failed.");
872                                         }
873                                 }
874                         }
875                 }
876         }
877         else
878         {
879                 r = ErrorMapToRetVal(retVal);
880                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
881                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
882         }
883
884         return pVideoMetadata.release();
885 }
886
887 ImageMetadata*
888 _ContentManagerUtilImpl::GetImageMetaN(const ByteBuffer& byteBuffer)
889 {
890         ClearLastResult();
891
892         int bufferLen = byteBuffer.GetRemaining();
893         SysTryReturn(NID_CNT, bufferLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The length of buffer is less than zero.");
894
895         // create object here as it needs to be passed to client in any case to make sure Get APIs do not crash
896         unique_ptr<ImageMetadata> pImageMetadata(new (nothrow) ImageMetadata());
897         SysTryReturn(NID_CNT, pImageMetadata != null, null, E_OUT_OF_MEMORY,
898                         "[E_OUT_OF_MEMORY] pImageMetadata is null.");
899
900         _ImageMetadataImpl* pImageMetaImpl = _ImageMetadataImpl::GetInstance(*(pImageMetadata.get()));
901         SysTryReturn(NID_CNT, pImageMetaImpl != null, null, E_OUT_OF_MEMORY,
902                         "[E_OUT_OF_MEMORY] pImageMetaImpl is null.");
903
904         ImageMeta* pMetadata = pImageMetaImpl->GetImageMetadata();
905         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
906                         "[E_INVALID_ARG] pMetadata is null.");
907
908         //assign by default here and overwrite below if width and height presents in EXIF data.
909         ImageFormat imgType = IMG_FORMAT_NONE;
910         int imageWidth = 0;
911         int imageHeight = 0;
912
913         result r = ImageBuffer::GetImageInfo(byteBuffer, imgType, imageWidth, imageHeight);
914         SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_INVALID_ARG,
915                         "[E_INVALID_ARG] GetImageInfo failed.");
916
917         pMetadata->width = imageWidth;
918         pMetadata->height = imageHeight;
919
920         if (imgType == IMG_FORMAT_JPG)
921         {
922                 const byte* pByte = byteBuffer.GetPointer();
923
924                 unique_ptr<ExifData, ExifDataDeleter> pExifdata(exif_data_new_from_data(pByte, bufferLen));
925                 if (pExifdata != null)
926                 {
927                         ExifTag tag;
928                         ExifByteOrder byteOrder;
929                         ExifEntry** pEntries = null;
930                         const char* pData = null;
931                         char buf[IMAGE_BUFF_LENGTH] = {0, };
932                         char mmBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store minutes value of GPS data
933                         char ssBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store seconds value of GPS data
934                         ExifContent* pExifcont[EXIF_IFD_COUNT];
935                         int index = 0;
936                         char latitudeRef = 0; // to store latitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
937                         char longitudeRef = 0; // to store longitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
938                         unsigned int entryCount = 0;
939
940                         for (int i = 0; i < EXIF_IFD_COUNT; i++)
941                         {
942                                 pExifcont[i] = pExifdata->ifd[i];
943                                 entryCount = pExifcont[i]->count;
944                                 pEntries = pExifcont[i]->entries;
945                                 for (unsigned int j = 0; j < entryCount; j++)
946                                 {
947                                         tag = pEntries[j]->tag;
948                                         pData = exif_entry_get_value(pEntries[j], buf, sizeof(buf));
949                                         SysTryReturn(NID_CNT, pData != null, pImageMetadata.release(), E_INVALID_ARG,
950                                                         "[E_INVALID_ARG] exif_entry_get_value failed.");
951
952                                         if (tag == EXIF_TAG_PIXEL_X_DIMENSION)
953                                         {
954                                                 pMetadata->width = atoi(buf);
955                                         }
956                                         else if (tag == EXIF_TAG_PIXEL_Y_DIMENSION)
957                                         {
958                                                 pMetadata->height = atoi(buf);
959                                         }
960                                         else if (tag == EXIF_TAG_MAKE)
961                                         {
962                                                 pMetadata->pManufacturer = new (nothrow) String(buf);
963                                                 SysTryReturn(NID_CNT, pMetadata->pManufacturer != null, null, E_OUT_OF_MEMORY,
964                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
965                                         }
966                                         else if (tag == EXIF_TAG_MODEL)
967                                         {
968                                                 pMetadata->pModel = new (nothrow) String(buf);
969                                                 SysTryReturn(NID_CNT, pMetadata->pModel != null, null, E_OUT_OF_MEMORY,
970                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
971                                         }
972                                         else if (tag == EXIF_TAG_DATE_TIME)
973                                         {
974                                                 pMetadata->pDateTime = new (nothrow) String(buf);
975                                                 SysTryReturn(NID_CNT, pMetadata->pDateTime != null, null, E_OUT_OF_MEMORY,
976                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
977                                         }
978                                         else if (tag == EXIF_TAG_ORIENTATION)
979                                         {
980                                                 //get the byte order(little endian or big endian) before extracting orientation type
981                                                 byteOrder = exif_data_get_byte_order(pEntries[j]->parent->parent);
982                                                 pMetadata->orientation = static_cast<ImageOrientationType>(exif_get_short(pEntries[j]->data, byteOrder));
983                                         }
984                                         else if (tag == EXIF_TAG_SOFTWARE)
985                                         {
986                                                 pMetadata->pSoftware = new (nothrow) String(buf);
987                                                 SysTryReturn(NID_CNT, pMetadata->pSoftware != null, null, E_OUT_OF_MEMORY,
988                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
989                                         }
990                                         else if (tag == EXIF_TAG_GPS_LATITUDE_REF)
991                                         {
992                                                 latitudeRef = buf[0]; // GPS Latitude reference value will be 'N'(NORTH) or 'S'(SOUTH)
993                                         }
994                                         else if (tag == EXIF_TAG_GPS_LATITUDE)
995                                         {
996                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
997                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
998                                                 {
999                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
1000                                                 }
1001                                                 index = 0; //re-assign index value as this is new buffer
1002                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
1003                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
1004                                                 {
1005                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
1006                                                 }
1007                                                 double ddVal = atof(buf); // degree value
1008                                                 double mmVal = atof(mmBuff); // minutesvalue
1009                                                 double ssVal = atof(ssBuff); // seconds value
1010                                                 pMetadata->latitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
1011
1012                                                 // if latitude designation is Southern (SOUTH) then latitude degree will be negative DD
1013                                                 if (latitudeRef == 'S')
1014                                                 {
1015                                                         pMetadata->latitude = (pMetadata->latitude * (double)(-1));
1016                                                 }
1017                                         }
1018                                         else if (tag == EXIF_TAG_GPS_LONGITUDE_REF)
1019                                         {
1020                                                 longitudeRef = buf[0]; // GPS Longitude reference value will be 'W'(WEST) or 'E'(EAST)
1021                                         }
1022                                         else if (tag == EXIF_TAG_GPS_LONGITUDE)
1023                                         {
1024                                                 index = 0; //re-assign index value as this is new buffer
1025                                                 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
1026                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
1027                                                 {
1028                                                         mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
1029                                                 }
1030                                                 index = 0; //re-assign index value as this is new buffer
1031                                                 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
1032                                                 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
1033                                                 {
1034                                                         ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
1035                                                 }
1036                                                 double ddVal = atof(buf); // degree value
1037                                                 double mmVal = atof(mmBuff); // minutesvalue
1038                                                 double ssVal = atof(ssBuff); // seconds value
1039                                                 pMetadata->longitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
1040
1041                                                 // if longitude designation is Western (WEST) then longitude degree will be negative DD
1042                                                 if (longitudeRef == 'W')
1043                                                 {
1044                                                         pMetadata->longitude = (pMetadata->longitude * (double)(-1));
1045                                                 }
1046                                         }
1047                                         else if (tag == EXIF_TAG_WHITE_BALANCE)
1048                                         {
1049                                                 pMetadata->pWhiteBalance = new (nothrow) String(buf);
1050                                                 SysTryReturn(NID_CNT, pMetadata->pWhiteBalance != null, null, E_OUT_OF_MEMORY,
1051                                                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1052                                         }
1053                                 }
1054                         }
1055                 }
1056         }
1057
1058         return pImageMetadata.release();
1059 }
1060
1061 //
1062 // E_SUCCESS
1063 // E_INVALID_ARG
1064 // E_OUT_OF_MEMORY
1065 //
1066 AudioMetadata*
1067 _ContentManagerUtilImpl::GetAudioMetaN(const ByteBuffer& byteBuffer)
1068 {
1069         ClearLastResult();
1070
1071         int bufferLen = byteBuffer.GetRemaining();
1072         SysTryReturn(NID_CNT, bufferLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The length of buffer is less than zero.");
1073
1074         // create here to make sure that get apis will not crash though the below API calls fails in case of invalid file.
1075         unique_ptr<AudioMetadata> pAudioMetadata(new (nothrow) AudioMetadata());
1076         SysTryReturn(NID_CNT, pAudioMetadata != null, null, E_OUT_OF_MEMORY,
1077                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1078
1079         _AudioMetadataImpl* pAudioMetaImpl = _AudioMetadataImpl::GetInstance(*(pAudioMetadata.get()));
1080         SysTryReturn(NID_CNT, pAudioMetaImpl != null, null, E_OUT_OF_MEMORY,
1081                         "[E_OUT_OF_MEMORY] pAudioMetaImpl is null.");
1082
1083         AudioMeta* pMetadata = pAudioMetaImpl->GetAudioMetadata();
1084         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
1085                         "[E_INVALID_ARG] pMetadata is null.");
1086
1087         // Create the metadata extractor handle
1088         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
1089         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
1090                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1091
1092         int retVal = metadata_extractor_create(pExtractor.get());
1093         result r = ErrorMapToRetVal(retVal);
1094         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1095                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
1096
1097         const byte* pByte = byteBuffer.GetPointer();
1098
1099         retVal = metadata_extractor_set_buffer(*(pExtractor.get()), pByte, bufferLen);
1100         r = ErrorMapToRetVal(retVal);
1101         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1102                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
1103
1104         // Get all relavent audio metadata by passing relavent attirbutes
1105         char* __pAudioMeta = null;
1106         unique_ptr<char, CharDeleter> pAudioMeta(null);
1107
1108         // bitrate
1109         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pAudioMeta);
1110         if (__pAudioMeta != null)
1111         {
1112                 pAudioMeta.reset(__pAudioMeta);
1113                 pMetadata->bitrate = atoi(pAudioMeta.get());
1114         }
1115         else
1116         {
1117                 r = ErrorMapToRetVal(retVal);
1118                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1119                                 "[%s] metadata_extractor_get_metadata(bitrate) failed.", GetErrorMessage(r));
1120         }
1121
1122         // channelcount
1123         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_CHANNELS, &__pAudioMeta);
1124         if (__pAudioMeta != null)
1125         {
1126                 pAudioMeta.reset(__pAudioMeta);
1127                 pMetadata->channelCount = atoi(pAudioMeta.get());
1128         }
1129         else
1130         {
1131                 r = ErrorMapToRetVal(retVal);
1132                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1133                                 "[%s] metadata_extractor_get_metadata(channels) failed.", GetErrorMessage(r));
1134         }
1135
1136         // duration
1137         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pAudioMeta);
1138         if (__pAudioMeta != null)
1139         {
1140                 pAudioMeta.reset(__pAudioMeta);
1141                 pMetadata->duration = atoi(pAudioMeta.get());
1142         }
1143         else
1144         {
1145                 r = ErrorMapToRetVal(retVal);
1146                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1147                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
1148         }
1149
1150         // frequency
1151         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_SAMPLERATE, &__pAudioMeta);
1152         if (__pAudioMeta != null)
1153         {
1154                 pAudioMeta.reset(__pAudioMeta);
1155                 pMetadata->frequency = atoi(pAudioMeta.get());
1156         }
1157         else
1158         {
1159                 r = ErrorMapToRetVal(retVal);
1160                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1161                                 "[%s] metadata_extractor_get_metadata(frequency) failed.", GetErrorMessage(r));
1162         }
1163
1164         // albumname
1165         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ALBUM, &__pAudioMeta);
1166         if (__pAudioMeta != null)
1167         {
1168                 pAudioMeta.reset(__pAudioMeta);
1169                 pMetadata->pAlbumName = new (nothrow) String(pAudioMeta.get());
1170                 SysTryReturn(NID_CNT, pMetadata->pAlbumName != null, null, E_OUT_OF_MEMORY,
1171                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1172         }
1173         else
1174         {
1175                 r = ErrorMapToRetVal(retVal);
1176                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1177                                 "[%s] metadata_extractor_get_metadata(album name) failed.", GetErrorMessage(r));
1178         }
1179
1180         // artist
1181         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ARTIST, &__pAudioMeta);
1182         if (pAudioMeta.get() != null)
1183         {
1184                 pAudioMeta.reset(__pAudioMeta);
1185                 pMetadata->pArtist = new (nothrow) String(pAudioMeta.get());
1186                 SysTryReturn(NID_CNT, pMetadata->pArtist != null, null, E_OUT_OF_MEMORY,
1187                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1188         }
1189         else
1190         {
1191                 r = ErrorMapToRetVal(retVal);
1192                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1193                                 "[%s] metadata_extractor_get_metadata(artist) failed.", GetErrorMessage(r));
1194         }
1195
1196         // copyright
1197         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COPYRIGHT, &__pAudioMeta);
1198         if (__pAudioMeta != null)
1199         {
1200                 pAudioMeta.reset(__pAudioMeta);
1201                 pMetadata->pCopyright = new (nothrow) String(pAudioMeta.get());
1202                 SysTryReturn(NID_CNT, pMetadata->pCopyright != null, null, E_OUT_OF_MEMORY,
1203                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1204         }
1205         else
1206         {
1207                 r = ErrorMapToRetVal(retVal);
1208                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1209                                 "[%s] metadata_extractor_get_metadata(copyright) failed.", GetErrorMessage(r));
1210         }
1211
1212         // genre
1213         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pAudioMeta);
1214         if (__pAudioMeta != null)
1215         {
1216                 pAudioMeta.reset(__pAudioMeta);
1217                 pMetadata->pGenre = new (nothrow) String(pAudioMeta.get());
1218                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
1219                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1220         }
1221         else
1222         {
1223                 r = ErrorMapToRetVal(retVal);
1224                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1225                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
1226         }
1227
1228         // title
1229         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TITLE, &__pAudioMeta);
1230         if (__pAudioMeta != null)
1231         {
1232                 pAudioMeta.reset(__pAudioMeta);
1233                 pMetadata->pTitle = new (nothrow) String(pAudioMeta.get());
1234                 SysTryReturn(NID_CNT, pMetadata->pTitle != null, null, E_OUT_OF_MEMORY,
1235                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1236         }
1237         else
1238         {
1239                 r = ErrorMapToRetVal(retVal);
1240                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1241                                 "[%s] metadata_extractor_get_metadata(title) failed.", GetErrorMessage(r));
1242         }
1243
1244         // comment
1245         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pAudioMeta);
1246         if (__pAudioMeta != null)
1247         {
1248                 pAudioMeta.reset(__pAudioMeta);
1249                 pMetadata->pComment = new (nothrow) String(pAudioMeta.get());
1250                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
1251                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1252         }
1253         else
1254         {
1255                 r = ErrorMapToRetVal(retVal);
1256                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1257                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
1258         }
1259
1260         // description
1261         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pAudioMeta);
1262         if (__pAudioMeta != null)
1263         {
1264                 pAudioMeta.reset(__pAudioMeta);
1265                 pMetadata->pDescription = new (nothrow) String(pAudioMeta.get());
1266                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
1267                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1268         }
1269         else
1270         {
1271                 r = ErrorMapToRetVal(retVal);
1272                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1273                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
1274         }
1275
1276         // recording date
1277         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_RECDATE, &__pAudioMeta);
1278         if (__pAudioMeta != null)
1279         {
1280                 pAudioMeta.reset(__pAudioMeta);
1281                 pMetadata->pRecordingDate = new (nothrow) String(pAudioMeta.get());
1282                 SysTryReturn(NID_CNT, pMetadata->pRecordingDate != null, null, E_OUT_OF_MEMORY,
1283                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1284         }
1285         else
1286         {
1287                 r = ErrorMapToRetVal(retVal);
1288                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1289                                 "[%s] metadata_extractor_get_metadata(recording date) failed.", GetErrorMessage(r));
1290         }
1291
1292         // author
1293         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUTHOR, &__pAudioMeta);
1294         if (__pAudioMeta != null)
1295         {
1296                 pAudioMeta.reset(__pAudioMeta);
1297                 pMetadata->pComposer = new (nothrow) String(pAudioMeta.get());
1298                 SysTryReturn(NID_CNT, pMetadata->pComposer != null, null, E_OUT_OF_MEMORY,
1299                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1300         }
1301         else
1302         {
1303                 r = ErrorMapToRetVal(retVal);
1304                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1305                                 "[%s] metadata_extractor_get_metadata(author) failed.", GetErrorMessage(r));
1306         }
1307
1308         // track info
1309         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TRACK_NUM, &__pAudioMeta);
1310         if (__pAudioMeta != null)
1311         {
1312                 pAudioMeta.reset(__pAudioMeta);
1313                 pMetadata->pTrackInfo = new (nothrow) String(pAudioMeta.get());
1314                 SysTryReturn(NID_CNT, pMetadata->pTrackInfo != null, null, E_OUT_OF_MEMORY,
1315                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1316
1317                 // if the string contains the track info like track num/track position,
1318                 // then track position will be ignored and only track num is returned
1319                 // no need to parse this string, since only track number is required
1320                 pMetadata->trackNum = atoi(pAudioMeta.get());
1321         }
1322         else
1323         {
1324                 r = ErrorMapToRetVal(retVal);
1325                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1326                                 "[%s] metadata_extractor_get_metadata(track info) failed.", GetErrorMessage(r));
1327         }
1328
1329         // date
1330         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DATE, &__pAudioMeta);
1331         if (__pAudioMeta != null)
1332         {
1333                 pAudioMeta.reset(__pAudioMeta);
1334                 pMetadata->year = atoi(pAudioMeta.get());
1335         }
1336         else
1337         {
1338                 r = ErrorMapToRetVal(retVal);
1339                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1340                                 "[%s] metadata_extractor_get_metadata(date) failed.", GetErrorMessage(r));
1341         }
1342
1343         // artwork
1344         int size = 0;
1345         void* __pArtwork = null;
1346         unique_ptr<void, VoidDeleter> pArtwork(null);
1347
1348         // Get the artwork image in media file
1349         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pAudioMeta);
1350
1351         //Check if the albumart present and pass it to client if it is successfully processed, otherwise ignore any errors
1352         //while processing albumart. This is to pass the other metadata tags to application.
1353         if (__pArtwork != null)
1354         {
1355                 pArtwork.reset(__pArtwork);
1356
1357                 Image img;
1358                 ImageFormat format = IMG_FORMAT_NONE;
1359                 ByteBuffer buffer;
1360
1361                 r = buffer.Construct(size);
1362                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
1363                 {
1364                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
1365                         if (!IsFailed(r))
1366                         {
1367                                 r = img.Construct();
1368                                 if (!IsFailed(r))
1369                                 {
1370                                         format = img.GetImageFormat(buffer);
1371                                         pMetadata->pThumbnail = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888,
1372                                                                          THUMBNAIL_IMAGE_WIDTH, THUMBNAIL_IMAGE_HEIGHT);
1373                                         if (pMetadata->pThumbnail == null)
1374                                         {
1375                                                 // Because Thumbnail is one of the metadata, it is not exception in this function.
1376                                                 SysLog(NID_CNT, "DecodeN failed.");
1377                                         }
1378                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
1379                                         if (pMetadata->pAlbumArt == null)
1380                                         {
1381                                                 // Because Album Art is one of the metadata, it is not exception in this function.
1382                                                 SysLog(NID_CNT, "DecodeN failed.");
1383                                         }
1384                                 }
1385                         }
1386                 }
1387         }
1388         else
1389         {
1390                 r = ErrorMapToRetVal(retVal);
1391                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
1392                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
1393         }
1394
1395         return pAudioMetadata.release();
1396 }
1397
1398 //
1399 // E_SUCCESS
1400 // E_INVALID_ARG
1401 // E_OUT_OF_MEMORY
1402 //
1403 VideoMetadata*
1404 _ContentManagerUtilImpl::GetVideoMetaN(const ByteBuffer& byteBuffer)
1405 {
1406         ClearLastResult();
1407
1408         int bufferLen = byteBuffer.GetRemaining();
1409         SysTryReturn(NID_CNT, bufferLen > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The length of buffer is less than zero.");
1410
1411         // need to create here to make sure that all get APIs will not crash in case of corrupted file
1412         unique_ptr<VideoMetadata> pVideoMetadata(new (nothrow) VideoMetadata());
1413         SysTryReturn(NID_CNT, pVideoMetadata != null, null, E_OUT_OF_MEMORY,
1414                         "[E_OUT_OF_MEMORY] The memory insufficient.");
1415
1416         _VideoMetadataImpl* pVideoMetaImpl = _VideoMetadataImpl::GetInstance(*(pVideoMetadata.get()));
1417         SysTryReturn(NID_CNT, pVideoMetaImpl != null, null, E_OUT_OF_MEMORY,
1418                         "[E_OUT_OF_MEMORY] pVideoMetaImpl is null.");
1419
1420         VideoMeta* pMetadata = pVideoMetaImpl->GetVideoMetadata();
1421         SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
1422                         "[E_INVALID_ARG] pMetadata is null.");
1423
1424         // Create the metadata extractor handle
1425         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
1426         SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
1427                                 "[E_OUT_OF_MEMORY] The memory insufficient.");
1428
1429         int retVal = metadata_extractor_create(pExtractor.get());
1430         result r = ErrorMapToRetVal(retVal);
1431         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1432                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
1433
1434         const byte* pByte = byteBuffer.GetPointer();
1435
1436         retVal = metadata_extractor_set_buffer(*(pExtractor.get()), pByte, bufferLen);
1437         r = ErrorMapToRetVal(retVal);
1438         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
1439                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
1440
1441         // Get all relavent video metadata by passing relavent attirbutes
1442         char* __pVideoMeta = null;
1443         unique_ptr<char, CharDeleter> pVideoMeta(null);
1444
1445         // width
1446         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_WIDTH, &__pVideoMeta);
1447         if (__pVideoMeta != null)
1448         {
1449                 pVideoMeta.reset(__pVideoMeta);
1450                 pMetadata->width = atoi(pVideoMeta.get());
1451         }
1452         else
1453         {
1454                 r = ErrorMapToRetVal(retVal);
1455                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1456                                 "[%s] metadata_extractor_get_metadata(width) failed.", GetErrorMessage(r));
1457         }
1458
1459         // height
1460         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_HEIGHT, &__pVideoMeta);
1461         if (__pVideoMeta != null)
1462         {
1463                 pVideoMeta.reset(__pVideoMeta);
1464                 pMetadata->height = atoi(pVideoMeta.get());
1465         }
1466         else
1467         {
1468                 r = ErrorMapToRetVal(retVal);
1469                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1470                                 "[%s] metadata_extractor_get_metadata(height) failed.", GetErrorMessage(r));
1471         }
1472
1473         // video bitrate
1474         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_BITRATE, &__pVideoMeta);
1475         if (__pVideoMeta != null)
1476         {
1477                 pVideoMeta.reset(__pVideoMeta);
1478                 pMetadata->videoBitrate = atoi(pVideoMeta.get());
1479         }
1480         else
1481         {
1482                 r = ErrorMapToRetVal(retVal);
1483                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1484                                 "[%s] metadata_extractor_get_metadata(video bitrate) failed.", GetErrorMessage(r));
1485         }
1486
1487         // audio bitrate
1488         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pVideoMeta);
1489         if (__pVideoMeta != null)
1490         {
1491                 pVideoMeta.reset(__pVideoMeta);
1492                 pMetadata->audioBitrate = atoi(pVideoMeta.get());
1493         }
1494         else
1495         {
1496                 r = ErrorMapToRetVal(retVal);
1497                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1498                                 "[%s] metadata_extractor_get_metadata(audio bitrate) failed.", GetErrorMessage(r));
1499         }
1500
1501         // framerate
1502         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_FPS, &__pVideoMeta);
1503         if (__pVideoMeta != null)
1504         {
1505                 pVideoMeta.reset(__pVideoMeta);
1506                 pMetadata->framerate = atoi(pVideoMeta.get());
1507         }
1508         else
1509         {
1510                 r = ErrorMapToRetVal(retVal);
1511                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1512                                 "[%s] metadata_extractor_get_metadata(framerate) failed.", GetErrorMessage(r));
1513         }
1514
1515         // duration
1516         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pVideoMeta);
1517         if (__pVideoMeta != null)
1518         {
1519                 pVideoMeta.reset(__pVideoMeta);
1520                 pMetadata->duration = atoi(pVideoMeta.get());
1521         }
1522         else
1523         {
1524                 r = ErrorMapToRetVal(retVal);
1525                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1526                                 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
1527         }
1528
1529         // genre
1530         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pVideoMeta);
1531         if (__pVideoMeta != null)
1532         {
1533                 pVideoMeta.reset(__pVideoMeta);
1534                 pMetadata->pGenre = new (nothrow) String(pVideoMeta.get()); //allocate memory
1535                 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
1536                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1537         }
1538         else
1539         {
1540                 r = ErrorMapToRetVal(retVal);
1541                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1542                                 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
1543         }
1544
1545         // comment
1546         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COMMENT, &__pVideoMeta);
1547         if (__pVideoMeta != null)
1548         {
1549                 pVideoMeta.reset(__pVideoMeta);
1550                 pMetadata->pComment = new (nothrow) String(pVideoMeta.get());
1551                 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
1552                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1553         }
1554         else
1555         {
1556                 r = ErrorMapToRetVal(retVal);
1557                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1558                                 "[%s] metadata_extractor_get_metadata(comment) failed.", GetErrorMessage(r));
1559         }
1560
1561         // description
1562         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pVideoMeta);
1563         if (__pVideoMeta != null)
1564         {
1565                 pVideoMeta.reset(__pVideoMeta);
1566                 pMetadata->pDescription = new (nothrow) String(pVideoMeta.get());
1567                 SysTryReturn(NID_CNT, pMetadata->pDescription != null, null, E_OUT_OF_MEMORY,
1568                                 "[E_OUT_OF_MEMORY] The memory is insufficient.");
1569         }
1570         else
1571         {
1572                 r = ErrorMapToRetVal(retVal);
1573                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1574                                 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
1575         }
1576
1577         // artwork
1578         int size = 0;
1579         void* __pArtwork = null;
1580         unique_ptr<void, VoidDeleter> pArtwork(null);
1581
1582         // Get the artwork image in media file
1583         retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pVideoMeta);
1584         if (__pArtwork != null)
1585         {
1586                 pArtwork.reset(__pArtwork);
1587
1588                 Image img;
1589                 ImageFormat format = IMG_FORMAT_NONE;
1590                 ByteBuffer buffer;
1591
1592                 r = buffer.Construct(size);
1593                 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
1594                 {
1595                         r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
1596                         if (!IsFailed(r))
1597                         {
1598                                 r = img.Construct();
1599                                 if (!IsFailed(r))
1600                                 {
1601                                         format = img.GetImageFormat(buffer);
1602
1603                                         pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
1604                                         if (pMetadata->pAlbumArt == null)
1605                                         {
1606                                                 // Because Album Art is one of the metadata, it is not exception in this function.
1607                                                 SysLog(NID_CNT, "DecodeN failed.");
1608                                         }
1609                                 }
1610                         }
1611                 }
1612         }
1613         else
1614         {
1615                 r = ErrorMapToRetVal(retVal);
1616                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
1617                                 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
1618         }
1619
1620         return pVideoMetadata.release();
1621 }
1622
1623 //
1624 // E_SUCCESS
1625 // E_INVALID_ARG
1626 // E_OUT_OF_MEMORY
1627 // E_FILE_NOT_FOUND
1628 // E_UNSUPPORTED_FORMAT
1629 //
1630 ContentType
1631 _ContentManagerUtilImpl::CheckContentType(const String& contentPath, bool internal)
1632 {
1633         ClearLastResult();
1634
1635         ContentType contentType = CONTENT_TYPE_UNKNOWN;
1636
1637         if (!internal)
1638         {
1639                 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), contentType, E_INVALID_ARG,
1640                                 "[E_INVALID_ARG] The path is not compatible.");
1641         }
1642         SysTryReturn(NID_CNT, contentPath.GetLength() != 0, contentType, E_INVALID_ARG,
1643                         "[E_INVALID_ARG] The length of contentPath is 0.");
1644         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), contentType, E_FILE_NOT_FOUND,
1645                         "[E_FILE_NOT_FOUND] The file corresponding to contentPath could not be found.");
1646
1647         String fileExt = _FileImpl::GetFileExtension(contentPath);
1648         result r = GetLastResult();
1649         SysTryReturn(NID_CNT, !IsFailed(r), contentType, r, "[%s] GetFileExtension failed.", GetErrorMessage(r));
1650
1651         unique_ptr<char[]> pFormat(_StringConverter::CopyToCharArrayN(fileExt));
1652         SysTryReturn(NID_CNT, pFormat != null, contentType, E_OUT_OF_MEMORY,
1653                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1654
1655         char* __pMimeType = null;
1656         int retVal = mime_type_get_mime_type(pFormat.get(), &__pMimeType);
1657         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, E_INVALID_ARG,
1658                         "[E_INVALID_ARG] mime_type_get_mime_type failed.");
1659         SysTryReturn(NID_CNT, __pMimeType != null, contentType, E_INVALID_ARG,
1660                         "[E_INVALID_ARG] mime_type_get_mime_type failed.");
1661
1662         unique_ptr<char, CharDeleter> pMimeType;
1663         pMimeType.reset(__pMimeType);
1664
1665         SysLog(NID_CNT, "The MIME type for %ls is %s", fileExt.GetPointer(), __pMimeType);
1666
1667         String mimeType(pMimeType.get());
1668
1669         if (mimeType.Contains(L"image"))
1670         {
1671                 return CONTENT_TYPE_IMAGE;
1672         }
1673         else if (mimeType.Contains(L"audio"))
1674         {
1675                 if (mimeType.Contains(L"x-mpegurl"))
1676                 {
1677                         SysLog(NID_CNT, "The type of x-mpegurl is other.");
1678                         return CONTENT_TYPE_OTHER;
1679                 }
1680                 return CONTENT_TYPE_AUDIO;
1681         }
1682         else if (mimeType.Contains(L"video"))
1683         {
1684                 String format;
1685                 fileExt.ToLowerCase(format);
1686
1687                 if (format == L"3gp" || format == L"mp4")
1688                 {
1689                         return CheckStream(contentPath);
1690                 }
1691                 return CONTENT_TYPE_VIDEO;
1692         }
1693         else if (mimeType.Contains(L"application"))
1694         {
1695                 if (mimeType.Contains(L"x-smaf"))
1696                 {
1697                         SysLog(NID_CNT, "The type of x-smaf is audio.");
1698                         return CONTENT_TYPE_AUDIO;
1699                 }
1700                 return CONTENT_TYPE_OTHER;
1701         }
1702
1703         return CONTENT_TYPE_OTHER;
1704 }
1705
1706 ContentType
1707 _ContentManagerUtilImpl::CheckStream(const String& contentPath)
1708 {
1709         ClearLastResult();
1710
1711         ContentType contentType = CONTENT_TYPE_UNKNOWN;
1712
1713         unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
1714         SysTryReturn(NID_CNT, pExtractor != null, contentType, E_OUT_OF_MEMORY,
1715                         "[E_OUT_OF_MEMORY] The memory is insufficient.");
1716
1717         int retVal = metadata_extractor_create(pExtractor.get());
1718         result r = ErrorMapToRetVal(retVal);
1719         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
1720                         "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
1721
1722         //Set the file path to extract metadata.
1723         unique_ptr<char[]> pContentPath(_StringConverter::CopyToCharArrayN(contentPath));
1724         SysTryReturn(NID_CNT, pContentPath != null, contentType, E_INVALID_ARG,
1725                         "[E_INVALID_ARG] The memory is insufficient.");
1726
1727         retVal = metadata_extractor_set_path(*(pExtractor.get()), pContentPath.get());
1728         r = ErrorMapToRetVal(retVal);
1729         SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE && pExtractor, contentType, r,
1730                         "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
1731
1732         //Check whether it is an audio or video file.
1733         char* __pAudio = null;
1734         unique_ptr<char, CharDeleter> pAudio(null);
1735
1736         char* __pVideo = null;
1737         unique_ptr<char, CharDeleter> pVideo(null);
1738
1739         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_HAS_AUDIO, &__pAudio);
1740         if (__pAudio != null)
1741         {
1742                 pAudio.reset(__pAudio);
1743         }
1744         else
1745         {
1746                 r = ErrorMapToRetVal(retVal);
1747                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
1748                                 "[%s] metadata_extractor_get_metadata failed.", GetErrorMessage(r));
1749         }
1750
1751         retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_HAS_VIDEO, &__pVideo);
1752         if (__pVideo != null)
1753         {
1754                 pVideo.reset(__pVideo);
1755         }
1756         else
1757         {
1758                 r = ErrorMapToRetVal(retVal);
1759                 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
1760                                 "[%s] metadata_extractor_get_metadata failed.", GetErrorMessage(r));
1761         }
1762
1763         if (*(pAudio.get()) > 0 && *(pVideo.get()) == 0)
1764         {
1765                 SysLog(NID_CNT, "The result of CheckStream() is audio");
1766                 return CONTENT_TYPE_AUDIO;
1767         }
1768         else if (*(pAudio.get()) == 0 && *(pVideo.get()) > 0)
1769         {
1770                 SysLog(NID_CNT, "The result of CheckStream() is video");
1771                 return CONTENT_TYPE_VIDEO;
1772         }
1773         else if (*(pAudio.get()) > 0 && *(pVideo.get()) > 0)
1774         {
1775                 SysLog(NID_CNT, "The result of CheckStream() is video");
1776                 return CONTENT_TYPE_VIDEO;
1777         }
1778         else
1779         {
1780                 SysLogException(NID_CNT, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] The stream is empty.");
1781         }
1782
1783         return contentType;
1784 }
1785
1786 bool
1787 _ContentManagerUtilImpl::VerifyFilePathCompatibility(const String& contentPath)
1788 {
1789         if (!_AppInfo::IsOspCompat())
1790         {
1791                 if (contentPath.StartsWith(OSP_MEDIA_PHONE, 0) || contentPath.StartsWith(OSP_MEDIA_MMC, 0)
1792                         || contentPath.StartsWith(OSP_HOME, 0))
1793                 {
1794                         SysLogException(NID_CNT, E_INVALID_ARG,
1795                                         "/Home, /Media/, or /Storagecard/Media/ is not supported from Tizen 2.0.");
1796                         return false;
1797                 }
1798         }
1799         else
1800         {
1801                 // prior to 2.0
1802                 if (!(contentPath.StartsWith(OSP_MEDIA_PHONE, 0) || contentPath.StartsWith(OSP_MEDIA_MMC, 0)
1803                         || contentPath.StartsWith(OSP_HOME, 0)))
1804                 {
1805                         SysLogException(NID_CNT, E_INVALID_ARG,
1806                                         "The contentPath should start with /Home, /Media, or /Storagecard/Media.");
1807                         return false;
1808                 }
1809         }
1810
1811         return true;
1812 }
1813
1814 result
1815 _ContentManagerUtilImpl::ErrorMapToRetVal(int retVal)
1816 {
1817         result r = E_SUCCESS;
1818
1819         switch (retVal)
1820         {
1821         case METADATA_EXTRACTOR_ERROR_NONE:
1822                 r = E_SUCCESS;
1823                 break;
1824         case METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER:
1825                 r = E_INVALID_ARG;
1826                 break;
1827         case METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY:
1828                 r = E_OUT_OF_MEMORY;
1829                 break;
1830         case METADATA_EXTRACTOR_ERROR_FILE_EXISTS:
1831                 r = E_INVALID_ARG;
1832                 break;
1833         case METADATA_EXTRACTOR_ERROR_OPERATION_FAILED:
1834                 r = E_INVALID_ARG;
1835                 break;
1836         }
1837
1838         return r;
1839 }
1840
1841 /**
1842  * deprecation
1843  */
1844 result
1845 _ContentManagerUtilImpl::CopyToMediaDirectory(const String& srcContentPath, const String& destContentPath)
1846 {
1847         ClearLastResult();
1848
1849         // For srcContentPath
1850         SysTryReturn(NID_CNT, !_FileImpl::IsSystemPath(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1851                 "[E_INVALID_ARG] Can not copy the file in the system region.");
1852         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1853                 "[E_INVALID_ARG] Can not find the file.");
1854
1855         // For destContentPath
1856         SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destContentPath), E_INVALID_ARG, E_INVALID_ARG,
1857                 "[E_INVALID_ARG] The destination path should start with /Media or /Storagecard/Media.");
1858
1859         // E_SUCCESS, E_INVALID_ARG, E_ILLEGAL_ACCESS, E_FILE_NOT_FOUND, E_FILE_ALREADY_EXIST, E_MAX_EXCEEDED, E_STORAGE_FULL, E_IO
1860         result r = E_SUCCESS;
1861         r = _FileImpl::Copy(srcContentPath, destContentPath, true);
1862         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] CopyToMediaDirectory failed.", GetErrorMessage(r));
1863
1864         return r;
1865 }
1866
1867 /**
1868  * deprecation
1869  */
1870 result
1871 _ContentManagerUtilImpl::MoveToMediaDirectory(const String& srcContentPath, const String& destContentPath)
1872 {
1873         ClearLastResult();
1874
1875         // For srcContentPath
1876         SysTryReturn(NID_CNT, !_FileImpl::IsSystemPath(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1877                 "[E_INVALID_ARG] Can not copy the file in the system region.");
1878         SysTryReturn(NID_CNT, _FileImpl::IsFileExist(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1879                 "[E_INVALID_ARG] Can not find the file.");
1880
1881         // For destContentPath
1882         SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destContentPath), E_INVALID_ARG, E_INVALID_ARG,
1883                 "[E_INVALID_ARG] The destination path should start with /Media or /Storagecard/Media.");
1884
1885         // E_SUCCESS, E_INVALID_ARG, E_ILLEGAL_ACCESS, E_FILE_NOT_FOUND, E_FILE_ALREADY_EXIST, E_MAX_EXCEEDED, E_STORAGE_FULL, E_IO
1886         result r = E_SUCCESS;
1887         r = _FileImpl::Move(srcContentPath, destContentPath);
1888         SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] MoveToMediaDirectory failed.", GetErrorMessage(r));
1889
1890         return r;
1891 }
1892 }}