2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
18 * @file FCnt_ContentManagerUtilImpl.cpp
19 * @brief This is the implementation file for the %_ContentManagerUtilImpl class.
21 * This file contains implementation of the %_ContentManagerUtilImpl class.
25 #include <mime_type.h>
26 #include <FBaseSysLog.h>
27 #include <FIoDirectory.h>
29 #include <FSysEnvironment.h>
30 #include <FMediaImage.h>
31 #include <FMediaImageUtil.h>
32 #include <FCntImageMetadata.h>
33 #include <FCntAudioMetadata.h>
34 #include <FCntVideoMetadata.h>
35 #include <FCnt_ContentManagerUtilImpl.h>
36 #include <FCnt_AudioMetadataImpl.h>
37 #include <FCnt_VideoMetadataImpl.h>
38 #include <FCnt_ImageMetadataImpl.h>
39 #include <FBase_StringConverter.h>
40 #include <FIo_FileImpl.h>
41 #include <FGrp_BitmapImpl.h>
42 #include <FMedia_ImageDecoder.h>
43 #include <FMedia_ImageImpl.h>
44 #include <FApp_AppInfo.h>
46 using namespace Tizen::Base;
47 using namespace Tizen::Io;
48 using namespace Tizen::Media;
49 using namespace Tizen::Graphics;
50 using namespace Tizen::App;
51 using namespace Tizen::System;
54 namespace Tizen { namespace Content
56 // Types of content, format supported and default values
57 static const int IMAGE_BUFF_LENGTH = 100;
58 static const int THUMBNAIL_IMAGE_WIDTH = 80;
59 static const int THUMBNAIL_IMAGE_HEIGHT = 60;
60 static const int MINUTES = 60;
61 static const int SECONDS = 3600; // 60*60
62 static const wchar_t CONTENT_FORMAT[] =
63 L"jpg1 JPG1 jpeg1 JPEG1 png1 PNG1 gif1 GIF1 wbmp1 WBMP1 bmp1 BMP1 tiff1 TIFF1 tif1 TIF1 \
64 mp32 MP32 aac2 AAC2 wma2 WMA2 m4a2 M4A2 3ga2 3GA2 midi2 MIDI2 mid2 MID2 mmf2 MMF2 \
65 wav2 WAV2 amr2 AMR2 imy2 IMY2 mxmf2 MXMF2 xmf2 XMF2 pmd2 PMD2 sdc2 SDC2 spm2 SPM2 flac2 FLAC2 pya2 PYA2 \
67 wmv3 WMV3 avi3 AVI3 asf3 ASF3 sdp3 SDP3 divx3 DIVX3 mkv3 MKV3 skm3 SKM3 k3g3 K3G3 pyv3 PYV3 rv3 RV3 \
68 rm3 RM3 ram3 RAM3 mov3 MOV3 qt3 QT3 mpeg3 MPEG3 flv3 FLV3 ra2 RA2 \
69 txt0 TXT0 fb20 FB20 smt0 SMT0 docx0 DOCX0 doc0 DOC0 pdf0 PDF0 pptx0 PPTX0 ppt0 PPT0 xlsx0 XLSX0 \
70 xls0 XLS0 html0 HTML0 htm0 HTM0 jad0 JAD0 jar0 JAR0 vbm0 VBM0 vcf0 VCF0 vcs0 VCS0 vmg0 VMG0 eml0 EML0 \
71 zse0 ZSE0 cer0 CER0 crt0 CRT0 der0 DER0 p120 P120 pfx0 PFX0 wgt0 WGT0 svgz0 SVGZ0 svg0 SVG0 swf0 SWF0 \
72 enc0 ENC0 ics0 ICS0 oap0 OAP0 mp45 MP45 3gpp5 3GPP5 3gp5 3GP5";
80 _ContentManagerUtilImpl::GetImageMetaN(const String& contentPath, bool internal)
86 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
87 "[E_INVALID_ARG] %ls is not compatible.", contentPath.GetPointer());
89 SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
90 "[E_INVALID_ARG] The file corresponding to contentPath could not be found.(%ls)", contentPath.GetPointer());
92 // create object here as it needs to be passed to client in any case to make sure Get APIs do not crash
93 unique_ptr<ImageMetadata> pImageMetadata(new (nothrow) ImageMetadata());
94 SysTryReturn(NID_CNT, pImageMetadata != null, null, E_OUT_OF_MEMORY,
95 "[E_OUT_OF_MEMORY] pImageMetadata is null.");
97 _ImageMetadataImpl* pImageMetaImpl = _ImageMetadataImpl::GetInstance(*(pImageMetadata.get()));
98 SysTryReturn(NID_CNT, pImageMetaImpl != null, null, E_OUT_OF_MEMORY,
99 "[E_OUT_OF_MEMORY] pImageMetaImpl is null.");
101 ImageMeta* pMetadata = pImageMetaImpl->GetImageMetadata();
102 SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
103 "[E_INVALID_ARG] pMetadata is null.");
105 //assign by default here and overwrite below if width and height presents in EXIF data.
106 ImageFormat imgType = IMG_FORMAT_NONE;
109 result r = _ImageImpl::GetImageInfo(contentPath, imgType, dim);
110 SysTryReturn(NID_CNT, r == E_SUCCESS, null, E_INVALID_ARG,
111 "[E_INVALID_ARG] GetImageInfo failed.");
113 pMetadata->width = dim.width;
114 pMetadata->height = dim.height;
115 pMetadata->contentPath = contentPath;
117 if (imgType == IMG_FORMAT_JPG)
119 unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
120 SysTryReturn(NID_CNT, pFileName != null, pImageMetadata.release(), E_OUT_OF_MEMORY,
121 "[E_OUT_OF_MEMORY] The memory is insufficient.");
123 unique_ptr<ExifData, ExifDataDeleter> pExifdata(exif_data_new_from_file(pFileName.get()));
124 if (pExifdata != null)
127 ExifByteOrder byteOrder;
128 ExifEntry** pEntries = null;
129 const char* pData = null;
130 char buf[IMAGE_BUFF_LENGTH] = {0, };
131 char mmBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store minutes value of GPS data
132 char ssBuff[IMAGE_BUFF_LENGTH] = {0, }; // to store seconds value of GPS data
133 ExifContent* pExifcont[EXIF_IFD_COUNT];
135 char latitudeRef = 0; // to store latitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
136 char longitudeRef = 0; // to store longitude reference (quadrasphere designation 'N', 'S', 'W' or 'E')
137 unsigned int entryCount = 0;
139 for (int i = 0; i < EXIF_IFD_COUNT; i++)
141 pExifcont[i] = pExifdata->ifd[i];
142 entryCount = pExifcont[i]->count;
143 pEntries = pExifcont[i]->entries;
144 for (unsigned int j = 0; j < entryCount; j++)
146 tag = pEntries[j]->tag;
147 pData = exif_entry_get_value(pEntries[j], buf, sizeof(buf));
148 SysTryReturn(NID_CNT, pData != null, pImageMetadata.release(), E_INVALID_ARG,
149 "[E_INVALID_ARG] exif_entry_get_value failed.");
151 if (tag == EXIF_TAG_PIXEL_X_DIMENSION)
153 pMetadata->width = atoi(buf);
155 else if (tag == EXIF_TAG_PIXEL_Y_DIMENSION)
157 pMetadata->height = atoi(buf);
159 else if (tag == EXIF_TAG_MAKE)
161 pMetadata->pManufacturer = new (nothrow) String(buf);
162 SysTryReturn(NID_CNT, pMetadata->pManufacturer != null, null, E_OUT_OF_MEMORY,
163 "[E_OUT_OF_MEMORY] The memory is insufficient.");
165 else if (tag == EXIF_TAG_MODEL)
167 pMetadata->pModel = new (nothrow) String(buf);
168 SysTryReturn(NID_CNT, pMetadata->pModel != null, null, E_OUT_OF_MEMORY,
169 "[E_OUT_OF_MEMORY] The memory is insufficient.");
171 else if (tag == EXIF_TAG_DATE_TIME)
173 pMetadata->pDateTime = new (nothrow) String(buf);
174 SysTryReturn(NID_CNT, pMetadata->pDateTime != null, null, E_OUT_OF_MEMORY,
175 "[E_OUT_OF_MEMORY] The memory is insufficient.");
177 else if (tag == EXIF_TAG_ORIENTATION)
179 //get the byte order(little endian or big endian) before extracting orientation type
180 byteOrder = exif_data_get_byte_order(pEntries[j]->parent->parent);
181 pMetadata->orientation = static_cast<ImageOrientationType>(exif_get_short(pEntries[j]->data, byteOrder));
183 else if (tag == EXIF_TAG_SOFTWARE)
185 pMetadata->pSoftware = new (nothrow) String(buf);
186 SysTryReturn(NID_CNT, pMetadata->pSoftware != null, null, E_OUT_OF_MEMORY,
187 "[E_OUT_OF_MEMORY] The memory is insufficient.");
189 else if (tag == EXIF_TAG_GPS_LATITUDE_REF)
191 latitudeRef = buf[0]; // GPS Latitude reference value will be 'N'(NORTH) or 'S'(SOUTH)
193 else if (tag == EXIF_TAG_GPS_LATITUDE)
195 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
196 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
198 mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
200 index = 0; //re-assign index value as this is new buffer
201 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
202 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
204 ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
206 double ddVal = atof(buf); // degree value
207 double mmVal = atof(mmBuff); // minutesvalue
208 double ssVal = atof(ssBuff); // seconds value
209 pMetadata->latitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
211 // if latitude designation is Southern (SOUTH) then latitude degree will be negative DD
212 if (latitudeRef == 'S')
214 pMetadata->latitude = (pMetadata->latitude * (double)(-1));
217 else if (tag == EXIF_TAG_GPS_LONGITUDE_REF)
219 longitudeRef = buf[0]; // GPS Longitude reference value will be 'W'(WEST) or 'E'(EAST)
221 else if (tag == EXIF_TAG_GPS_LONGITUDE)
223 index = 0; //re-assign index value as this is new buffer
224 ParseBuffer(buf, index); // to extract the minutes value of GPS data, if present
225 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
227 mmBuff[l] = buf[l + index + 1]; //add 1 to skip the ','
229 index = 0; //re-assign index value as this is new buffer
230 ParseBuffer(mmBuff, index); // to extract the seconds value of GPS data, if present
231 for (int l = 0; l < IMAGE_BUFF_LENGTH-1; l++)
233 ssBuff[l] = mmBuff[l + index + 1]; //add 1 to skip the ','
235 double ddVal = atof(buf); // degree value
236 double mmVal = atof(mmBuff); // minutesvalue
237 double ssVal = atof(ssBuff); // seconds value
238 pMetadata->longitude = ddVal + (mmVal/MINUTES) + (ssVal/SECONDS);
240 // if longitude designation is Western (WEST) then longitude degree will be negative DD
241 if (longitudeRef == 'W')
243 pMetadata->longitude = (pMetadata->longitude * (double)(-1));
246 else if (tag == EXIF_TAG_WHITE_BALANCE)
248 pMetadata->pWhiteBalance = new (nothrow) String(buf);
249 SysTryReturn(NID_CNT, pMetadata->pWhiteBalance != null, null, E_OUT_OF_MEMORY,
250 "[E_OUT_OF_MEMORY] The memory is insufficient.");
257 return pImageMetadata.release();
261 _ContentManagerUtilImpl::ParseBuffer(char* pBuffer, int& count)
263 if ((*pBuffer != ',') && (*pBuffer != '\0')) // parse the buffer till ',' or '\0' and return the index
265 ParseBuffer(++pBuffer, ++count);
275 _ContentManagerUtilImpl::GetAudioMetaN(const String& contentPath)
279 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
280 "[E_INVALID_ARG] %ls is not compatible.", contentPath.GetPointer());
281 SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
282 "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
284 // create here to make sure that get apis will not crash though the below API calls fails in case of invalid file.
285 unique_ptr<AudioMetadata> pAudioMetadata(new (nothrow) AudioMetadata());
286 SysTryReturn(NID_CNT, pAudioMetadata != null, null, E_OUT_OF_MEMORY,
287 "[E_OUT_OF_MEMORY] The memory is insufficient.");
289 _AudioMetadataImpl* pAudioMetaImpl = _AudioMetadataImpl::GetInstance(*(pAudioMetadata.get()));
290 SysTryReturn(NID_CNT, pAudioMetaImpl != null, null, E_OUT_OF_MEMORY,
291 "[E_OUT_OF_MEMORY] pAudioMetaImpl is null.");
293 AudioMeta* pMetadata = pAudioMetaImpl->GetAudioMetadata();
294 SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
295 "[E_INVALID_ARG] pMetadata is null.");
297 pMetadata->contentPath = contentPath;
299 // Create the metadata extractor handle
300 unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
301 SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
302 "[E_OUT_OF_MEMORY] The memory is insufficient.");
304 int retVal = metadata_extractor_create(pExtractor.get());
305 result r = ErrorMapToRetVal(retVal);
306 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
307 "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
309 // Set file path of content to extract the metadata
310 unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
311 SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
312 "[E_OUT_OF_MEMORY] The memory is insufficient.");
314 retVal = metadata_extractor_set_path(*(pExtractor.get()), pFileName.get());
315 r = ErrorMapToRetVal(retVal);
316 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
317 "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
319 // Get all relavent audio metadata by passing relavent attirbutes
320 char* __pAudioMeta = null;
321 unique_ptr<char, CharDeleter> pAudioMeta(null);
324 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pAudioMeta);
325 if (__pAudioMeta != null)
327 pAudioMeta.reset(__pAudioMeta);
328 pMetadata->bitrate = atoi(pAudioMeta.get());
332 r = ErrorMapToRetVal(retVal);
333 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
334 "[%s] metadata_extractor_get_metadata(bitrate) failed.", GetErrorMessage(r));
338 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_CHANNELS, &__pAudioMeta);
339 if (__pAudioMeta != null)
341 pAudioMeta.reset(__pAudioMeta);
342 pMetadata->channelCount = atoi(pAudioMeta.get());
346 r = ErrorMapToRetVal(retVal);
347 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
348 "[%s] metadata_extractor_get_metadata(channels) failed.", GetErrorMessage(r));
352 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pAudioMeta);
353 if (__pAudioMeta != null)
355 pAudioMeta.reset(__pAudioMeta);
356 pMetadata->duration = atoi(pAudioMeta.get());
360 r = ErrorMapToRetVal(retVal);
361 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
362 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
366 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_SAMPLERATE, &__pAudioMeta);
367 if (__pAudioMeta != null)
369 pAudioMeta.reset(__pAudioMeta);
370 pMetadata->frequency = atoi(pAudioMeta.get());
374 r = ErrorMapToRetVal(retVal);
375 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
376 "[%s] metadata_extractor_get_metadata(frequency) failed.", GetErrorMessage(r));
380 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ALBUM, &__pAudioMeta);
381 if (__pAudioMeta != null)
383 pAudioMeta.reset(__pAudioMeta);
384 pMetadata->pAlbumName = new (nothrow) String(pAudioMeta.get());
385 SysTryReturn(NID_CNT, pMetadata->pAlbumName != null, null, E_OUT_OF_MEMORY,
386 "[E_OUT_OF_MEMORY] The memory is insufficient.");
390 r = ErrorMapToRetVal(retVal);
391 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
392 "[%s] metadata_extractor_get_metadata(album name) failed.", GetErrorMessage(r));
396 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_ARTIST, &__pAudioMeta);
397 if (pAudioMeta.get() != null)
399 pAudioMeta.reset(__pAudioMeta);
400 pMetadata->pArtist = new (nothrow) String(pAudioMeta.get());
401 SysTryReturn(NID_CNT, pMetadata->pArtist != null, null, E_OUT_OF_MEMORY,
402 "[E_OUT_OF_MEMORY] The memory is insufficient.");
406 r = ErrorMapToRetVal(retVal);
407 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
408 "[%s] metadata_extractor_get_metadata(artist) failed.", GetErrorMessage(r));
412 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_COPYRIGHT, &__pAudioMeta);
413 if (__pAudioMeta != null)
415 pAudioMeta.reset(__pAudioMeta);
416 pMetadata->pCopyright = new (nothrow) String(pAudioMeta.get());
417 SysTryReturn(NID_CNT, pMetadata->pCopyright != null, null, E_OUT_OF_MEMORY,
418 "[E_OUT_OF_MEMORY] The memory is insufficient.");
422 r = ErrorMapToRetVal(retVal);
423 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
424 "[%s] metadata_extractor_get_metadata(copyright) failed.", GetErrorMessage(r));
428 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pAudioMeta);
429 if (__pAudioMeta != null)
431 pAudioMeta.reset(__pAudioMeta);
432 pMetadata->pGenre = new (nothrow) String(pAudioMeta.get());
433 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
434 "[E_OUT_OF_MEMORY] The memory is insufficient.");
438 r = ErrorMapToRetVal(retVal);
439 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
440 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
444 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TITLE, &__pAudioMeta);
445 if (__pAudioMeta != null)
447 pAudioMeta.reset(__pAudioMeta);
448 pMetadata->pTitle = new (nothrow) String(pAudioMeta.get());
449 SysTryReturn(NID_CNT, pMetadata->pTitle != null, null, E_OUT_OF_MEMORY,
450 "[E_OUT_OF_MEMORY] The memory is insufficient.");
454 r = ErrorMapToRetVal(retVal);
455 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
456 "[%s] metadata_extractor_get_metadata(title) failed.", GetErrorMessage(r));
460 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DESCRIPTION, &__pAudioMeta);
461 if (__pAudioMeta != null)
463 pAudioMeta.reset(__pAudioMeta);
464 pMetadata->pComment = new (nothrow) String(pAudioMeta.get());
465 SysTryReturn(NID_CNT, pMetadata->pComment != null, null, E_OUT_OF_MEMORY,
466 "[E_OUT_OF_MEMORY] The memory is insufficient.");
470 r = ErrorMapToRetVal(retVal);
471 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
472 "[%s] metadata_extractor_get_metadata(description) failed.", GetErrorMessage(r));
476 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_RECDATE, &__pAudioMeta);
477 if (__pAudioMeta != null)
479 pAudioMeta.reset(__pAudioMeta);
480 pMetadata->pRecordingDate = new (nothrow) String(pAudioMeta.get());
481 SysTryReturn(NID_CNT, pMetadata->pRecordingDate != null, null, E_OUT_OF_MEMORY,
482 "[E_OUT_OF_MEMORY] The memory is insufficient.");
486 r = ErrorMapToRetVal(retVal);
487 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
488 "[%s] metadata_extractor_get_metadata(recording date) failed.", GetErrorMessage(r));
492 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUTHOR, &__pAudioMeta);
493 if (__pAudioMeta != null)
495 pAudioMeta.reset(__pAudioMeta);
496 pMetadata->pComposer = new (nothrow) String(pAudioMeta.get());
497 SysTryReturn(NID_CNT, pMetadata->pComposer != null, null, E_OUT_OF_MEMORY,
498 "[E_OUT_OF_MEMORY] The memory is insufficient.");
502 r = ErrorMapToRetVal(retVal);
503 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
504 "[%s] metadata_extractor_get_metadata(author) failed.", GetErrorMessage(r));
508 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_TRACK_NUM, &__pAudioMeta);
509 if (__pAudioMeta != null)
511 pAudioMeta.reset(__pAudioMeta);
512 pMetadata->pTrackInfo = new (nothrow) String(pAudioMeta.get());
513 SysTryReturn(NID_CNT, pMetadata->pTrackInfo != null, null, E_OUT_OF_MEMORY,
514 "[E_OUT_OF_MEMORY] The memory is insufficient.");
516 // if the string contains the track info like track num/track position,
517 // then track position will be ignored and only track num is returned
518 // no need to parse this string, since only track number is required
519 pMetadata->trackNum = atoi(pAudioMeta.get());
523 r = ErrorMapToRetVal(retVal);
524 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
525 "[%s] metadata_extractor_get_metadata(track info) failed.", GetErrorMessage(r));
529 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DATE, &__pAudioMeta);
530 if (__pAudioMeta != null)
532 pAudioMeta.reset(__pAudioMeta);
533 pMetadata->year = atoi(pAudioMeta.get());
537 r = ErrorMapToRetVal(retVal);
538 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
539 "[%s] metadata_extractor_get_metadata(date) failed.", GetErrorMessage(r));
544 void* __pArtwork = null;
545 unique_ptr<void, VoidDeleter> pArtwork(null);
547 // Get the artwork image in media file
548 retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pAudioMeta);
550 //Check if the albumart present and pass it to client if it is successfully processed, otherwise ignore any errors
551 //while processing albumart. This is to pass the other metadata tags to application.
552 if (__pArtwork != null)
554 pArtwork.reset(__pArtwork);
557 ImageFormat format = IMG_FORMAT_NONE;
560 r = buffer.Construct(size);
561 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
563 r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
569 format = img.GetImageFormat(buffer);
570 pMetadata->pThumbnail = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888,
571 THUMBNAIL_IMAGE_WIDTH, THUMBNAIL_IMAGE_HEIGHT);
572 if (pMetadata->pThumbnail == null)
574 // Because Thumbnail is one of the metadata, it is not exception in this function.
575 SysLog(NID_CNT, "DecodeN failed.");
577 pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
578 if (pMetadata->pAlbumArt == null)
580 // Because Album Art is one of the metadata, it is not exception in this function.
581 SysLog(NID_CNT, "DecodeN failed.");
589 r = ErrorMapToRetVal(retVal);
590 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pAudioMetadata.release(), r,
591 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
594 return pAudioMetadata.release();
603 _ContentManagerUtilImpl::GetVideoMetaN(const String& contentPath)
607 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), null, E_INVALID_ARG,
608 "[E_INVALID_ARG] %ls is not compatible.", contentPath.GetPointer());
609 SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), null, E_INVALID_ARG,
610 "[E_INVALID_ARG] The file corresponding to contentPath could not be found.");
612 // need to create here to make sure that all get APIs will not crash in case of corrupted file
613 unique_ptr<VideoMetadata> pVideoMetadata(new (nothrow) VideoMetadata());
614 SysTryReturn(NID_CNT, pVideoMetadata != null, null, E_OUT_OF_MEMORY,
615 "[E_OUT_OF_MEMORY] The memory insufficient.");
617 _VideoMetadataImpl* pVideoMetaImpl = _VideoMetadataImpl::GetInstance(*(pVideoMetadata.get()));
618 SysTryReturn(NID_CNT, pVideoMetaImpl != null, null, E_OUT_OF_MEMORY,
619 "[E_OUT_OF_MEMORY] pVideoMetaImpl is null.");
621 VideoMeta* pMetadata = pVideoMetaImpl->GetVideoMetadata();
622 SysTryReturn(NID_CNT, pMetadata != null, null, E_INVALID_ARG,
623 "[E_INVALID_ARG] pMetadata is null.");
625 pMetadata->contentPath = contentPath;
627 // Create the metadata extractor handle
628 unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
629 SysTryReturn(NID_CNT, pExtractor != null, null, E_OUT_OF_MEMORY,
630 "[E_OUT_OF_MEMORY] The memory insufficient.");
632 int retVal = metadata_extractor_create(pExtractor.get());
633 result r = ErrorMapToRetVal(retVal);
634 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
635 "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
637 // Set file path of content to extract the metadata
638 unique_ptr<char[]> pFileName(_StringConverter::CopyToCharArrayN(contentPath));
639 SysTryReturn(NID_CNT, pFileName != null, null, E_OUT_OF_MEMORY,
640 "[E_OUT_OF_MEMORY] The memory is insufficient.");
642 retVal = metadata_extractor_set_path(*(pExtractor.get()), pFileName.get());
643 r = ErrorMapToRetVal(retVal);
644 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, null, r,
645 "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
647 // Get all relavent video metadata by passing relavent attirbutes
648 char* __pVideoMeta = null;
649 unique_ptr<char, CharDeleter> pVideoMeta(null);
652 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_WIDTH, &__pVideoMeta);
653 if (__pVideoMeta != null)
655 pVideoMeta.reset(__pVideoMeta);
656 pMetadata->width = atoi(pVideoMeta.get());
660 r = ErrorMapToRetVal(retVal);
661 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
662 "[%s] metadata_extractor_get_metadata(width) failed.", GetErrorMessage(r));
666 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_HEIGHT, &__pVideoMeta);
667 if (__pVideoMeta != null)
669 pVideoMeta.reset(__pVideoMeta);
670 pMetadata->height = atoi(pVideoMeta.get());
674 r = ErrorMapToRetVal(retVal);
675 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
676 "[%s] metadata_extractor_get_metadata(height) failed.", GetErrorMessage(r));
680 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_BITRATE, &__pVideoMeta);
681 if (__pVideoMeta != null)
683 pVideoMeta.reset(__pVideoMeta);
684 pMetadata->videoBitrate = atoi(pVideoMeta.get());
688 r = ErrorMapToRetVal(retVal);
689 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
690 "[%s] metadata_extractor_get_metadata(video bitrate) failed.", GetErrorMessage(r));
694 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_AUDIO_BITRATE, &__pVideoMeta);
695 if (__pVideoMeta != null)
697 pVideoMeta.reset(__pVideoMeta);
698 pMetadata->audioBitrate = atoi(pVideoMeta.get());
702 r = ErrorMapToRetVal(retVal);
703 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
704 "[%s] metadata_extractor_get_metadata(audio bitrate) failed.", GetErrorMessage(r));
708 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_VIDEO_FPS, &__pVideoMeta);
709 if (__pVideoMeta != null)
711 pVideoMeta.reset(__pVideoMeta);
712 pMetadata->framerate = atoi(pVideoMeta.get());
716 r = ErrorMapToRetVal(retVal);
717 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
718 "[%s] metadata_extractor_get_metadata(framerate) failed.", GetErrorMessage(r));
722 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_DURATION, &__pVideoMeta);
723 if (__pVideoMeta != null)
725 pVideoMeta.reset(__pVideoMeta);
726 pMetadata->duration = atoi(pVideoMeta.get());
730 r = ErrorMapToRetVal(retVal);
731 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
732 "[%s] metadata_extractor_get_metadata(duration) failed.", GetErrorMessage(r));
736 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_GENRE, &__pVideoMeta);
737 if (__pVideoMeta != null)
739 pVideoMeta.reset(__pVideoMeta);
740 pMetadata->pGenre = new (nothrow) String(pVideoMeta.get()); //allocate memory
741 SysTryReturn(NID_CNT, pMetadata->pGenre != null, null, E_OUT_OF_MEMORY,
742 "[E_OUT_OF_MEMORY] The memory is insufficient.");
746 r = ErrorMapToRetVal(retVal);
747 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
748 "[%s] metadata_extractor_get_metadata(genre) failed.", GetErrorMessage(r));
753 void* __pArtwork = null;
754 unique_ptr<void, VoidDeleter> pArtwork(null);
756 // Get the artwork image in media file
757 retVal = metadata_extractor_get_artwork(*(pExtractor.get()), &__pArtwork, &size, &__pVideoMeta);
758 if (__pArtwork != null)
760 pArtwork.reset(__pArtwork);
763 ImageFormat format = IMG_FORMAT_NONE;
766 r = buffer.Construct(size);
767 if (!IsFailed(r)) //Ignore the error codes to send other metadata to app
769 r = buffer.SetArray((const byte*)(pArtwork.get()), 0, size);
775 format = img.GetImageFormat(buffer);
777 pMetadata->pAlbumArt = img.DecodeN(buffer, format, BITMAP_PIXEL_FORMAT_ARGB8888);
778 if (pMetadata->pAlbumArt == null)
780 // Because Album Art is one of the metadata, it is not exception in this function.
781 SysLog(NID_CNT, "DecodeN failed.");
789 r = ErrorMapToRetVal(retVal);
790 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, pVideoMetadata.release(), r,
791 "[%s] metadata_extractor_get_artwork failed.", GetErrorMessage(r));
794 return pVideoMetadata.release();
802 // E_UNSUPPORTED_FORMAT
805 _ContentManagerUtilImpl::CheckContentType(const String& contentPath, bool internal)
809 ContentType contentType = CONTENT_TYPE_UNKNOWN;
813 SysTryReturn(NID_CNT, VerifyFilePathCompatibility(contentPath), contentType, E_INVALID_ARG,
814 "[E_INVALID_ARG] %ls is not compatible.", contentPath.GetPointer());
816 SysTryReturn(NID_CNT, contentPath.GetLength() != 0, contentType, E_INVALID_ARG,
817 "[E_INVALID_ARG] The length of contentPath is 0.");
818 SysTryReturn(NID_CNT, _FileImpl::IsFileExist(contentPath), contentType, E_FILE_NOT_FOUND,
819 "[E_FILE_NOT_FOUND] The file corresponding to contentPath could not be found.");
820 String fileExt = _FileImpl::GetFileExtension(contentPath);
822 // The type of ISMA and ISMV can be changed from other to video.
824 fileExt.ToLowerCase(format);
826 if (format == L"isma" || format == L"ismv")
828 contentType = GetDrmFileType(format);
829 result r = GetLastResult();
830 SysTryReturn(NID_CNT, !IsFailed(r), contentType, r, "[%s] GetDrmFileType failed.", GetErrorMessage(r));
837 result r = String(CONTENT_FORMAT).LastIndexOf(format, String(CONTENT_FORMAT).GetLength() - 1, index);
840 if (r == E_OBJ_NOT_FOUND)
842 SysLogException(NID_CNT, E_UNSUPPORTED_FORMAT,
843 "[E_UNSUPPORTED_FORMAT] The file format is not supported[%ls].", format.GetPointer());
847 SysLogException(NID_CNT, E_INVALID_ARG,
848 "[E_INVALID_ARG] The contentPath is invalid[%ls].", contentPath.GetPointer());
854 int length = fileExt.GetLength();
856 r = String(CONTENT_FORMAT).SubString(index+length, 1, subStr);
857 SysTryReturn(NID_CNT, !(IsFailed(r)), contentType, E_INVALID_ARG, "[E_INVALID_ARG] SubString failed.");
859 SysLog(NID_CNT, "index = %d, length = %d, subStr = %ls", index, length, subStr.GetPointer());
861 const String image(L"1");
862 const String audio(L"2");
863 const String video(L"3");
864 const String other(L"0");
865 const String audioOrVideo(L"5");
867 if (subStr.CompareTo(image) == 0)
869 return CONTENT_TYPE_IMAGE;
871 else if (subStr.CompareTo(audio) == 0)
873 return CONTENT_TYPE_AUDIO;
875 else if (subStr.CompareTo(video) == 0)
877 return CONTENT_TYPE_VIDEO;
879 else if (subStr.CompareTo(other) == 0)
881 return CONTENT_TYPE_OTHER;
883 else if (subStr.CompareTo(audioOrVideo) == 0)
885 //Create metadata extractor handle
886 unique_ptr<metadata_extractor_h, ExtractorDeleter> pExtractor(new (nothrow) metadata_extractor_h);
887 SysTryReturn(NID_CNT, pExtractor != null, contentType, E_OUT_OF_MEMORY,
888 "[E_OUT_OF_MEMORY] The memory is insufficient.");
890 int retVal = metadata_extractor_create(pExtractor.get());
891 result r = ErrorMapToRetVal(retVal);
892 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
893 "[%s] metadata_extractor_create failed.", GetErrorMessage(r));
895 //Set file path of content to extract metadata.
896 unique_ptr<char[]> pContentPath(_StringConverter::CopyToCharArrayN(contentPath));
897 SysTryReturn(NID_CNT, pContentPath != null, contentType, E_INVALID_ARG,
898 "[E_INVALID_ARG] The memory is insufficient.");
900 retVal = metadata_extractor_set_path(*(pExtractor.get()), pContentPath.get());
901 r = ErrorMapToRetVal(retVal);
902 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE && pExtractor, contentType, r,
903 "[%s] metadata_extractor_set_path failed.", GetErrorMessage(r));
905 //Get the metadata info, to check whether audio or video present in the file
906 char* __pAudio = null;
907 unique_ptr<char> pAudio(null);
909 char* __pVideo = null;
910 unique_ptr<char> pVideo(null);
912 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_HAS_AUDIO, &__pAudio);
913 if (__pAudio != null)
915 pAudio.reset(__pAudio);
919 r = ErrorMapToRetVal(retVal);
920 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
921 "[%s] metadata_extractor_get_metadata failed.", GetErrorMessage(r));
924 retVal = metadata_extractor_get_metadata(*(pExtractor.get()), METADATA_HAS_VIDEO, &__pVideo);
925 if (__pVideo != null)
927 pVideo.reset(__pVideo);
931 r = ErrorMapToRetVal(retVal);
932 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, contentType, r,
933 "[%s] metadata_extractor_get_metadata failed.", GetErrorMessage(r));
936 if (*(pAudio.get()) > 0 && *(pVideo.get()) == 0)
938 contentType = CONTENT_TYPE_AUDIO;
940 else if (*(pAudio.get()) == 0 && *(pVideo.get()) > 0)
942 contentType = CONTENT_TYPE_VIDEO;
944 else if (*(pAudio.get()) > 0 && *(pVideo.get()) > 0)
946 contentType = CONTENT_TYPE_VIDEO;
950 SysLogException(NID_CNT, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] The stream is empty.");
955 // The file extension is invalid(.jp, .bm, .m).
956 SysLogException(NID_CNT, E_UNSUPPORTED_FORMAT,
957 "[E_UNSUPPORTED_FORMAT] The file extension is invalid[%ls].", subStr.GetPointer());
964 _ContentManagerUtilImpl::GetDrmFileType(const String& fileExt)
968 unique_ptr<char[]> pFormat(_StringConverter::CopyToCharArrayN(fileExt));
969 SysTryReturn(NID_CNT, pFormat != null, CONTENT_TYPE_UNKNOWN, E_OUT_OF_MEMORY,
970 "The memory is insufficient.");
972 char* __pMimeType = null;
973 int retVal = mime_type_get_mime_type(pFormat.get(), &__pMimeType);
974 SysTryReturn(NID_CNT, retVal == METADATA_EXTRACTOR_ERROR_NONE, CONTENT_TYPE_UNKNOWN, E_INVALID_ARG,
975 "mime_type_get_mime_type failed.");
976 SysTryReturn(NID_CNT, __pMimeType != null, CONTENT_TYPE_UNKNOWN, E_INVALID_ARG,
977 "mime_type_get_mime_type failed.");
979 unique_ptr<char, CharDeleter> pMimeType;
980 pMimeType.reset(__pMimeType);
982 SysLog(NID_CNT, "The MIME type for %ls is %s", fileExt.GetPointer(), __pMimeType);
984 String mimeType(pMimeType.get());
986 if (mimeType == L"audio/mp4")
988 return CONTENT_TYPE_AUDIO;
990 else if (mimeType == L"video/mp4")
992 return CONTENT_TYPE_VIDEO;
994 else if (mimeType == L"application/octet-stream")
996 return CONTENT_TYPE_OTHER;
1000 SysLogException(NID_CNT, E_UNSUPPORTED_FORMAT, "The MIME type is invalid.");
1003 return CONTENT_TYPE_UNKNOWN;
1007 _ContentManagerUtilImpl::VerifyFilePathCompatibility(const String& contentPath)
1009 if (!_AppInfo::IsOspCompat())
1011 if (contentPath.StartsWith(OSP_MEDIA_PHONE, 0) || contentPath.StartsWith(OSP_MEDIA_MMC, 0)
1012 || contentPath.StartsWith(OSP_HOME, 0))
1014 SysLogException(NID_CNT, E_INVALID_ARG,
1015 "/Home, /Media/, or /Storagecard/Media/ is not supported from Tizen 2.0.");
1022 if (!(contentPath.StartsWith(OSP_MEDIA_PHONE, 0) || contentPath.StartsWith(OSP_MEDIA_MMC, 0)
1023 || contentPath.StartsWith(OSP_HOME, 0)))
1025 SysLogException(NID_CNT, E_INVALID_ARG,
1026 "The contentPath should start with /Home, /Media, or /Storagecard/Media.");
1035 _ContentManagerUtilImpl::ErrorMapToRetVal(int retVal)
1037 result r = E_SUCCESS;
1041 case METADATA_EXTRACTOR_ERROR_NONE:
1044 case METADATA_EXTRACTOR_ERROR_INVALID_PARAMETER:
1047 case METADATA_EXTRACTOR_ERROR_OUT_OF_MEMORY:
1048 r = E_OUT_OF_MEMORY;
1050 case METADATA_EXTRACTOR_ERROR_FILE_EXISTS:
1053 case METADATA_EXTRACTOR_ERROR_OPERATION_FAILED:
1065 _ContentManagerUtilImpl::CopyToMediaDirectory(const String& srcContentPath, const String& destContentPath)
1069 // For srcContentPath
1070 SysTryReturn(NID_CNT, !_FileImpl::IsSystemPath(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1071 "[E_INVALID_ARG] Can not copy the file in the system region.");
1072 SysTryReturn(NID_CNT, _FileImpl::IsFileExist(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1073 "[E_INVALID_ARG] Can not find the file.");
1075 // For destContentPath
1076 SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destContentPath), E_INVALID_ARG, E_INVALID_ARG,
1077 "[E_INVALID_ARG] The destination path should start with /Media or /Storagecard/Media.");
1079 // E_SUCCESS, E_INVALID_ARG, E_ILLEGAL_ACCESS, E_FILE_NOT_FOUND, E_FILE_ALREADY_EXIST, E_MAX_EXCEEDED, E_STORAGE_FULL, E_IO
1080 result r = E_SUCCESS;
1081 r = _FileImpl::Copy(srcContentPath, destContentPath, true);
1082 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] CopyToMediaDirectory failed.", GetErrorMessage(r));
1091 _ContentManagerUtilImpl::MoveToMediaDirectory(const String& srcContentPath, const String& destContentPath)
1095 // For srcContentPath
1096 SysTryReturn(NID_CNT, !_FileImpl::IsSystemPath(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1097 "[E_INVALID_ARG] Can not copy the file in the system region.");
1098 SysTryReturn(NID_CNT, _FileImpl::IsFileExist(srcContentPath), E_INVALID_ARG, E_INVALID_ARG,
1099 "[E_INVALID_ARG] Can not find the file.");
1101 // For destContentPath
1102 SysTryReturn(NID_CNT, _FileImpl::IsMediaPath(destContentPath), E_INVALID_ARG, E_INVALID_ARG,
1103 "[E_INVALID_ARG] The destination path should start with /Media or /Storagecard/Media.");
1105 // E_SUCCESS, E_INVALID_ARG, E_ILLEGAL_ACCESS, E_FILE_NOT_FOUND, E_FILE_ALREADY_EXIST, E_MAX_EXCEEDED, E_STORAGE_FULL, E_IO
1106 result r = E_SUCCESS;
1107 r = _FileImpl::Move(srcContentPath, destContentPath);
1108 SysTryReturn(NID_CNT, !IsFailed(r), r, r, "[%s] MoveToMediaDirectory failed.", GetErrorMessage(r));