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