2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.1 (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
8 // http://floralicense.org/license/
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.
18 * @file: ThumbnailManager.cpp
19 * @brief: This file contains the implementation of ThumbnailManager class,
20 * which manages creation of Thumbnails for each folder entry.
26 #include <FGraphics.h>
29 #include "MfThumbnailManager.h"
30 #include "MfUtility.h"
31 #include "MfMyFilesApp.h"
33 using namespace Tizen::App;
34 using namespace Tizen::Base::Collection;
35 using namespace Tizen::Graphics;
37 static ThumbnailManager* thumbnailManager = null;
40 static const wchar_t* IDB_VIDEO_PLAY_THUMB_BIG = L"U01_thumbnail_icon_video.png";
43 using namespace Tizen::App;
44 using namespace Tizen::Base;
45 using namespace Tizen::Base::Collection;
46 using namespace Tizen::Base::Runtime;
47 using namespace Tizen::Content;
48 using namespace Tizen::Graphics;
49 using namespace Tizen::Media;
52 ThumbnailManager::GetInstance(void)
54 if (thumbnailManager == null)
58 return thumbnailManager;
62 ThumbnailManager::CreateInstance(void)
66 thumbnailManager = new (std::nothrow) ThumbnailManager();
67 r = thumbnailManager->Construct();
76 std::atexit(DeleteInstance);
80 ThumbnailManager::DeleteInstance(void)
82 if (thumbnailManager != null)
84 /*thumbnailManager->Stop();
85 thumbnailManager->Join();*/
87 delete thumbnailManager;
88 thumbnailManager = null;
92 ThumbnailManager::Construct(void)
95 r = Thread::Construct(THREAD_TYPE_EVENT_DRIVEN);
97 AppResource* pAppResource = null;
98 pAppResource = Application::GetInstance()->GetAppResource();
100 __pDummyImage = pAppResource->GetBitmapN(IDB_DUMMY_IMG, BITMAP_PIXEL_FORMAT_ARGB8888);
106 ThumbnailManager::ThumbnailManager(void)
107 : __pCurrentThumbReq(null)
108 , __pDummyImage(null)
110 //Empty Implementation.
113 ThumbnailManager::~ThumbnailManager(void)
115 ClearCurrentThumbRequest();
116 delete __pDummyImage;
119 ThumbnailManager::ThumbnailManager(const ThumbnailManager& thumbnailManager)
121 __pCurrentThumbReq = null;
125 ThumbnailManager::operator =(const ThumbnailManager& thumbnailManager)
127 if (this != &thumbnailManager)
129 __pCurrentThumbReq = thumbnailManager.__pCurrentThumbReq;
136 ThumbnailManager::GetThumbnail(ThumbRequest* pRequest)
138 result r = E_SUCCESS;
139 ThumbMgrResultValues thumbMgrRes = THUMB_MGR_RES_SUCCESS;
141 AppResource* pAppResource = null;
143 Bitmap* pTempBitmap = null;
144 Bitmap* pBitmapToMerge = null;
145 Bitmap* pMergedThumbnail = null;
147 ImageBuffer* pVideoFrameBuff = null;
148 ImageBuffer* pRotatedImgBuff = null;
150 Tizen::Content::ImageMetadata* pImageMeta = null;
151 VideoFrameExtractor extractor;
152 RecordingRotation videoRecordingRotation;
153 Bitmap* pTmpBmp = null;
155 ImageBuffer* pRotatedImgBuffer = null;
157 ImageBuffer ImgBuffer;
159 ImageFormat imgFormat;
160 ExifOrientation imgOrientation;
163 bool GenerateThumbnail = false;
164 bool IsVideoFile = false;
167 TryCatch((pRequest != null) && (pRequest->iRquestId > -1) && (pRequest->FilePath.IsEmpty() == false), thumbMgrRes = THUMB_MGR_RES_FAILED, "ThumbRequest is NULL, Thumbnail genrataion failed!");
169 pAppResource = Application::GetInstance()->GetAppResource();
170 pBitmapToMerge = pAppResource->GetBitmapN(IDB_VIDEO_PLAY_SMALL, BITMAP_PIXEL_FORMAT_ARGB8888);
171 if (pBitmapToMerge != null)
173 pBitmapToMerge->Scale(Dimension(ID_THUMBNAIL_WIDH, ID_THUMBNAIL_HEIGHT));
177 pTempBitmap = MakeBitmapN(pRequest->FilePath, GenerateThumbnail, IsVideoFile);
178 if (GenerateThumbnail)
182 r = extractor.Construct(pRequest->FilePath, MEDIA_PIXEL_FORMAT_BGRA8888);
184 // Extracts video frames from the video file
187 pVideoFrameBuff = extractor.GetFrameN(0);
188 if ( pVideoFrameBuff !=null)
190 videoRecordingRotation = extractor.GetRecordingRotation();
191 if ( videoRecordingRotation == RECORDING_ROTATION_90 )
192 pRotatedImgBuff = pVideoFrameBuff->RotateN(IMAGE_ROTATION_90);
193 else if ( videoRecordingRotation == RECORDING_ROTATION_180 )
194 pRotatedImgBuff = pVideoFrameBuff->RotateN(IMAGE_ROTATION_180);
195 else if ( videoRecordingRotation == RECORDING_ROTATION_270 )
196 pRotatedImgBuff = pVideoFrameBuff->RotateN(IMAGE_ROTATION_270);
198 pRotatedImgBuff = extractor.GetFrameN(0);
200 if ( pRotatedImgBuff !=null )
201 pRequest->pBitmap = pRotatedImgBuff->GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
203 pRequest->pBitmap = pVideoFrameBuff->GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
205 TryCatch(pRequest->pBitmap != null, r = E_OUT_OF_MEMORY, "FRAMEEXTRACTOR : failed to allocate memory to pTempBitmap");
209 delete pVideoFrameBuff;
210 pVideoFrameBuff = null;
213 if (pRotatedImgBuff != null)
215 delete pRotatedImgBuff;
216 pRotatedImgBuff = null;
220 if( pRequest->pBitmap==null)
222 pRequest->pBitmap = new (std::nothrow) Bitmap();
224 r = pRequest->pBitmap->Construct(*__pDummyImage, Rectangle(0, 0, __pDummyImage->GetWidth(), __pDummyImage->GetHeight()));
229 pMergedThumbnail = MfUtility::MergeBitmapN(pRequest->pBitmap, pBitmapToMerge, ID_THUMBNAIL_WIDH, ID_THUMBNAIL_HEIGHT);
230 if (pMergedThumbnail != null)
232 pRequest->pBitmap = pMergedThumbnail;
233 AppLogDebug("Bitmap Merging Completed Successfully: [%s]", GetErrorMessage(GetLastResult()));
235 pBitmapToMerge = null;
243 AppLogDebug("VideoThumbnail:STOP");
244 thumbMgrRes = THUMB_MGR_RES_SUCCESS;
248 pImageMeta = ContentManagerUtil::GetImageMetaN(pRequest->FilePath);
251 pTmpBmp = pImageMeta->GetThumbnailN();
254 ImageBuffer::GetImageInfo(pRequest->FilePath, imgFormat, width, height);
255 ImgBuffer.Construct(pRequest->FilePath,width, height, IMAGE_SCALING_METHOD_FAST_BILINEAR );
256 imgOrientation = ImgBuffer.GetExifOrientation();
258 if (imgOrientation == EXIF_ORIENTATION_RIGHT_TOP ||
259 imgOrientation == EXIF_ORIENTATION_TOP_RIGHT )
261 pRotatedImgBuffer = ImgBuffer.RotateN(IMAGE_ROTATION_90);
263 else if (imgOrientation == EXIF_ORIENTATION_RIGHT_BOTTOM ||
264 imgOrientation == EXIF_ORIENTATION_BOTTOM_RIGHT)
266 pRotatedImgBuffer = ImgBuffer.RotateN(IMAGE_ROTATION_180);
268 else if (imgOrientation == EXIF_ORIENTATION_LEFT_BOTTOM ||
269 imgOrientation == EXIF_ORIENTATION_BOTTOM_LEFT)
271 pRotatedImgBuffer = ImgBuffer.RotateN(IMAGE_ROTATION_270);
274 if ( pRotatedImgBuffer !=null )
276 pRequest->pBitmap = pRotatedImgBuffer->GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
280 pRequest->pBitmap = pTmpBmp; //ImgBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
283 if( pRequest->pBitmap == null )
284 pRequest->pBitmap = pTmpBmp;
286 if ( pRotatedImgBuffer!=null )
288 delete pRotatedImgBuffer;
289 pRotatedImgBuffer = null;
291 AppLogDebug("Image Orientation [%d]", pImageMeta->GetOrientation() );
296 r = ImgBuffer.Construct(pRequest->FilePath,THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, IMAGE_SCALING_METHOD_FAST_BILINEAR );
297 pRequest->pBitmap = ImgBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
301 thumbMgrRes = THUMB_MGR_RES_SUCCESS;
305 TryCatch(pTempBitmap != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Thumbnail generation failed");
306 thumbMgrRes = THUMB_MGR_RES_SUCCESS;
307 pRequest->pBitmap = pTempBitmap;
310 if ( pImageMeta != null )
316 TryCatch(pTempBitmap != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Thumbnail generation failed");
317 thumbMgrRes = THUMB_MGR_RES_SUCCESS;
318 pRequest->pBitmap = pTempBitmap;
321 if (pBitmapToMerge != null)
323 delete pBitmapToMerge;
324 pBitmapToMerge = null;
327 AppLogDebug("Exit [%s]:", GetErrorMessage(r));
332 AppLogDebug("Exit Error Message[%s]:", GetErrorMessage(r));
334 if (pRequest != null)
336 pRequest->pBitmap = null;
339 if (pTempBitmap != null)
342 if (pMergedThumbnail)
343 delete pMergedThumbnail;
345 if ( pImageMeta != null )
353 ThumbnailManager::GetThumbnailN(Tizen::Base::String& FilePath, Tizen::Graphics::Dimension& Dim)
355 bool GenerateThumbnail = false;
356 bool IsVideoFile = false;
357 result r = E_SUCCESS;
359 Bitmap* pTempBitmap = null;
360 Bitmap* pThumbBitmap = null;
361 Bitmap* pTmpBmp = null;
363 ImageMetadata* pImageMeta = null;
365 if (FilePath.IsEmpty() || FilePath.GetLength() == 0)
370 pTempBitmap = MakeBitmapN(FilePath, GenerateThumbnail, IsVideoFile);
371 TryCatch(pTempBitmap != null, r = E_FAILURE, "Thumbnail Generation failed");
373 if (GenerateThumbnail)
377 VideoFrameExtractor extractor;
378 result r = extractor.Construct(FilePath, MEDIA_PIXEL_FORMAT_BGRA8888);
380 // Extracts video frames from the video file
381 ImageBuffer* pImage = extractor.GetFrameN(0);
382 if ( pImage != null )
384 pThumbBitmap = pImage->GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_AUTO);
385 TryCatch(pThumbBitmap != null, r = E_OUT_OF_MEMORY, "FRAMEEXTRACTOR : failed to allocate memory to pTempBitmap");
391 pImageMeta = ContentManagerUtil::GetImageMetaN(FilePath);
395 pTmpBmp = pImageMeta->GetThumbnailN();
398 pThumbBitmap = new (std::nothrow) Bitmap();
399 TryCatch(pThumbBitmap != null, r = E_OUT_OF_MEMORY, "failed to allocate memory to pTempBitmap");
400 pThumbBitmap->Construct(*pTmpBmp, Rectangle(0, 0, Dim.width, Dim.height));
404 pThumbBitmap = pTempBitmap;
416 TryCatch(pTempBitmap != null, r = E_FAILURE, "Thumbnail Generation failed");
417 pThumbBitmap = pTempBitmap;
425 if (pTempBitmap != null)
435 ThumbnailManager::MakeBitmapN(const Tizen::Base::String& FilePath, bool& makeThumbnail, bool& bVideo)
437 result r = E_SUCCESS;
439 ImageBuffer* imageBuffer = null;
440 Bitmap* pTempBitmap = null;
441 AppResource* pAppResource = null;
442 ContentType contentType = CONTENT_TYPE_UNKNOWN;
443 BitmapPixelFormat pixelFormat = BITMAP_PIXEL_FORMAT_MIN;
444 ThumbMgrResultValues thumbMgrRes = THUMB_MGR_RES_SUCCESS;
448 pAppResource = Application::GetInstance()->GetAppResource();
449 TryCatch(pAppResource != null, r = E_OUT_OF_MEMORY, "Could not locate app resource manager!");
451 contentType = MfUtility::GetContentType(FilePath);
455 case CONTENT_TYPE_IMAGE:
457 if (FilePath.EndsWith(L"png") || FilePath.EndsWith(L"PNG"))
459 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
460 makeThumbnail = true;
466 pixelFormat = BITMAP_PIXEL_FORMAT_RGB565;
467 makeThumbnail = true;
474 case CONTENT_TYPE_AUDIO:
476 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
477 makeThumbnail = false;
478 pTempBitmap = pAppResource->GetBitmapN(IDB_MUSIC, pixelFormat);
482 case CONTENT_TYPE_VIDEO:
484 makeThumbnail = true;
489 case CONTENT_TYPE_OTHER:
491 makeThumbnail = false;
493 if (FilePath.EndsWith(L"pdf") || FilePath.EndsWith(L"PDF"))
495 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
496 pTempBitmap = pAppResource->GetBitmapN(IDB_PDF, pixelFormat);
499 else if (FilePath.EndsWith(L"doc") || FilePath.EndsWith(L"DOC"))
501 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
502 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_WORD, pixelFormat);
505 else if (FilePath.EndsWith(L"docx") || FilePath.EndsWith(L"DOCX"))
507 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
508 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_WORD, pixelFormat);
511 else if (FilePath.EndsWith(L"xls") || FilePath.EndsWith(L"XLS"))
513 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
514 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_EXCEL, pixelFormat);
517 else if (FilePath.EndsWith(L"xlsx") || FilePath.EndsWith(L"XLSX"))
519 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
520 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_EXCEL, pixelFormat);
523 else if (FilePath.EndsWith(L"ppt") || FilePath.EndsWith(L"PPT"))
525 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
526 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_PPT, pixelFormat);
529 else if (FilePath.EndsWith(L"pptx") || FilePath.EndsWith(L"PPTX"))
531 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
532 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_PPT, pixelFormat);
535 else if (FilePath.EndsWith(L"html") || FilePath.EndsWith(L"HTML") || FilePath.EndsWith(L"htm") ||
536 FilePath.EndsWith(L"HTM") || FilePath.EndsWith(L"JS") || FilePath.EndsWith(L"js"))
538 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
539 pTempBitmap = pAppResource->GetBitmapN(IDB_HTML, pixelFormat);
542 else if (FilePath.EndsWith(L"rss") || FilePath.EndsWith(L"RSS"))
544 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
545 pTempBitmap = pAppResource->GetBitmapN(IDB_RSS, pixelFormat);
548 else if (FilePath.EndsWith(L"txt") || FilePath.EndsWith(L"TXT"))
550 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
551 pTempBitmap = pAppResource->GetBitmapN(IDB_TEXT, pixelFormat);
554 else if (FilePath.EndsWith(L"SVF") || FilePath.EndsWith(L"svg"))
556 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
557 pTempBitmap = pAppResource->GetBitmapN(IDB_SVG, pixelFormat);
560 else if (FilePath.EndsWith(L"swf") || FilePath.EndsWith(L"SWF"))
562 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
563 pTempBitmap = pAppResource->GetBitmapN(IDB_SWF, pixelFormat);
566 else if (FilePath.EndsWith(L"tpk") || FilePath.EndsWith(L"TPK") || FilePath.EndsWith(L"wgt") || FilePath.EndsWith(L"WGT"))
568 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
569 pTempBitmap = pAppResource->GetBitmapN(IDB_TPK, pixelFormat);
572 else if (FilePath.EndsWith(L"VCF") || FilePath.EndsWith(L"vcf"))
574 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
575 pTempBitmap = pAppResource->GetBitmapN(IDB_VCARD, pixelFormat);
578 else if (FilePath.EndsWith(L"vcs") || FilePath.EndsWith(L"VCS"))
580 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
581 pTempBitmap = pAppResource->GetBitmapN(IDB_VCALENDAR, pixelFormat);
586 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
587 pTempBitmap = pAppResource->GetBitmapN(IDB_UNKNOWN, pixelFormat);
592 case CONTENT_TYPE_UNKNOWN:
594 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
595 makeThumbnail = false;
596 pTempBitmap = pAppResource->GetBitmapN(IDB_UNKNOWN, pixelFormat);
600 case CONTENT_TYPE_ALL:
602 //Empty Implementation
607 imageBuffer = new (std::nothrow) ImageBuffer();
608 TryCatch(imageBuffer != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Failed to allocate memory to imageBuffer");
610 r = imageBuffer->Construct(FilePath, null, true);
611 TryCatch(r == E_SUCCESS, thumbMgrRes = THUMB_MGR_RES_FAILED, "Failed to construct to image decoder");
613 pTempBitmap = imageBuffer->GetBitmapN(pixelFormat, BUFFER_SCALING_AUTO);
614 TryCatch(pTempBitmap != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Failed to decode bitmap");
616 if (imageBuffer != null)
621 AppLogDebug("EXIT: r = %s", GetErrorMessage(r));
625 makeThumbnail = false;
628 if (imageBuffer != null)
633 AppLogDebug("EXIT: Error Message [%s]", GetErrorMessage(r));
637 ThumbnailManager::SetThumbnailSize(void /*Tizen::Graphics::Dimension& dim*/)
643 Tizen::Graphics::Dimension&
644 ThumbnailManager::GetDefaultThumbSize(void)
650 ThumbnailManager::ClearCurrentThumbRequest(void)
652 result r = E_SUCCESS;
653 if (__pCurrentThumbReq)
655 __pCurrentThumbReq = null;
660 ThumbnailManager::OnUserEventReceivedN(RequestId requestId, Tizen::Base::Collection::IList* pArgs)
662 ThumbRequest* pTempThumbReq = null;
663 ArrayList* pTempArrayList = null;
664 result r = E_SUCCESS;
668 case ThumbnailManager::THUMB_MGR_GET_THUMBNAIL:
670 TryCatch(pArgs != null, r = E_FAILURE, "Argument list is null");
671 pTempThumbReq = (ThumbRequest*) pArgs->GetAt(0);
672 TryCatch(pTempThumbReq != null, r = E_FAILURE, "Request is null!");
674 __pCurrentThumbReq = pTempThumbReq;
675 TryCatch(__pCurrentThumbReq != null, , "E_FAILURE Current Request is null");
677 if (GetThumbnail(__pCurrentThumbReq) == THUMB_MGR_RES_SUCCESS)
679 pTempArrayList = new (std::nothrow) ArrayList();
680 pTempArrayList->Construct();
681 pTempArrayList->Add(pTempThumbReq);
682 Application::GetInstance()->SendUserEvent(THUMBNAIL_LAODED, pTempArrayList);
686 if (__pCurrentThumbReq != null)
688 if (__pCurrentThumbReq->pBitmap != null)
690 delete __pCurrentThumbReq->pBitmap;
691 __pCurrentThumbReq->pBitmap = null;
694 Application::GetInstance()->SendUserEvent(THUMBNAIL_FAILED, null);
699 case ThumbnailManager::THUMB_MGR_STOP:
701 ClearCurrentThumbRequest();
707 AppLogDebug("Unsupported case reached!");
708 Application::GetInstance()->SendUserEvent(THUMBNAIL_CANCELED, null);
714 ClearCurrentThumbRequest();
717 pArgs->RemoveAll(true);
720 Application::GetInstance()->SendUserEvent(THUMBNAIL_FAILED, null);
725 ThumbnailManager::StopThumbnailManagerThread(void)
727 result r = E_SUCCESS;
730 AppLogDebug("Exit : %s", GetErrorMessage(r));