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