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