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 r = ImgBuffer.Construct(pRequest->FilePath,width, height, IMAGE_SCALING_METHOD_FAST_BILINEAR );
256 TryCatch(r == E_SUCCESS, , "ImageBuffer::Construct failed");
258 imgOrientation = ImgBuffer.GetExifOrientation();
259 TryCatch(GetLastResult() == E_SUCCESS, , "ImageBuffer::GetExifOrientation failed");
261 if (imgOrientation == EXIF_ORIENTATION_RIGHT_TOP ||
262 imgOrientation == EXIF_ORIENTATION_TOP_RIGHT )
264 pRotatedImgBuffer = ImgBuffer.RotateN(IMAGE_ROTATION_90);
266 else if (imgOrientation == EXIF_ORIENTATION_RIGHT_BOTTOM ||
267 imgOrientation == EXIF_ORIENTATION_BOTTOM_RIGHT)
269 pRotatedImgBuffer = ImgBuffer.RotateN(IMAGE_ROTATION_180);
271 else if (imgOrientation == EXIF_ORIENTATION_LEFT_BOTTOM ||
272 imgOrientation == EXIF_ORIENTATION_BOTTOM_LEFT)
274 pRotatedImgBuffer = ImgBuffer.RotateN(IMAGE_ROTATION_270);
277 if ( pRotatedImgBuffer !=null )
279 pRequest->pBitmap = pRotatedImgBuffer->GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
283 pRequest->pBitmap = pTmpBmp; //ImgBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
286 if( pRequest->pBitmap == null )
287 pRequest->pBitmap = pTmpBmp;
289 if ( pRotatedImgBuffer!=null )
291 delete pRotatedImgBuffer;
292 pRotatedImgBuffer = null;
294 AppLogDebug("Image Orientation [%d]", pImageMeta->GetOrientation() );
299 r = ImgBuffer.Construct(pRequest->FilePath,THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, IMAGE_SCALING_METHOD_FAST_BILINEAR );
300 TryCatch(r == E_SUCCESS, , "ImageBuffer::Construct failed");
301 pRequest->pBitmap = ImgBuffer.GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_NONE);
305 thumbMgrRes = THUMB_MGR_RES_SUCCESS;
309 TryCatch(pTempBitmap != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Thumbnail generation failed");
310 thumbMgrRes = THUMB_MGR_RES_SUCCESS;
311 pRequest->pBitmap = pTempBitmap;
314 if ( pImageMeta != null )
320 TryCatch(pTempBitmap != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Thumbnail generation failed");
321 thumbMgrRes = THUMB_MGR_RES_SUCCESS;
322 pRequest->pBitmap = pTempBitmap;
325 if (pBitmapToMerge != null)
327 delete pBitmapToMerge;
328 pBitmapToMerge = null;
331 AppLogDebug("Exit [%s]:", GetErrorMessage(r));
336 AppLogDebug("Exit Error Message[%s]:", GetErrorMessage(r));
338 if (pRequest != null)
340 pRequest->pBitmap = null;
343 if (pTempBitmap != null)
346 if (pMergedThumbnail)
347 delete pMergedThumbnail;
349 if ( pImageMeta != null )
357 ThumbnailManager::GetThumbnailN(Tizen::Base::String& FilePath, Tizen::Graphics::Dimension& Dim)
359 bool GenerateThumbnail = false;
360 bool IsVideoFile = false;
361 result r = E_SUCCESS;
363 Bitmap* pTempBitmap = null;
364 Bitmap* pThumbBitmap = null;
365 Bitmap* pTmpBmp = null;
367 ImageMetadata* pImageMeta = null;
369 if (FilePath.IsEmpty() || FilePath.GetLength() == 0)
374 pTempBitmap = MakeBitmapN(FilePath, GenerateThumbnail, IsVideoFile);
375 TryCatch(pTempBitmap != null, r = E_FAILURE, "Thumbnail Generation failed");
377 if (GenerateThumbnail)
381 VideoFrameExtractor extractor;
382 result r = extractor.Construct(FilePath, MEDIA_PIXEL_FORMAT_BGRA8888);
384 // Extracts video frames from the video file
385 ImageBuffer* pImage = extractor.GetFrameN(0);
386 if ( pImage != null )
388 pThumbBitmap = pImage->GetBitmapN(BITMAP_PIXEL_FORMAT_ARGB8888, BUFFER_SCALING_AUTO);
389 TryCatch(pThumbBitmap != null, r = E_OUT_OF_MEMORY, "FRAMEEXTRACTOR : failed to allocate memory to pTempBitmap");
395 pImageMeta = ContentManagerUtil::GetImageMetaN(FilePath);
399 pTmpBmp = pImageMeta->GetThumbnailN();
402 pThumbBitmap = new (std::nothrow) Bitmap();
403 TryCatch(pThumbBitmap != null, r = E_OUT_OF_MEMORY, "failed to allocate memory to pTempBitmap");
404 pThumbBitmap->Construct(*pTmpBmp, Rectangle(0, 0, Dim.width, Dim.height));
408 pThumbBitmap = pTempBitmap;
420 TryCatch(pTempBitmap != null, r = E_FAILURE, "Thumbnail Generation failed");
421 pThumbBitmap = pTempBitmap;
429 if (pTempBitmap != null)
439 ThumbnailManager::MakeBitmapN(const Tizen::Base::String& FilePath, bool& makeThumbnail, bool& bVideo)
441 result r = E_SUCCESS;
443 ImageBuffer* imageBuffer = null;
444 Bitmap* pTempBitmap = null;
445 AppResource* pAppResource = null;
446 ContentType contentType = CONTENT_TYPE_UNKNOWN;
447 BitmapPixelFormat pixelFormat = BITMAP_PIXEL_FORMAT_MIN;
448 ThumbMgrResultValues thumbMgrRes = THUMB_MGR_RES_SUCCESS;
452 pAppResource = Application::GetInstance()->GetAppResource();
453 TryCatch(pAppResource != null, r = E_OUT_OF_MEMORY, "Could not locate app resource manager!");
455 contentType = MfUtility::GetContentType(FilePath);
459 case CONTENT_TYPE_IMAGE:
461 if (FilePath.EndsWith(L"png") || FilePath.EndsWith(L"PNG"))
463 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
464 makeThumbnail = true;
470 pixelFormat = BITMAP_PIXEL_FORMAT_RGB565;
471 makeThumbnail = true;
478 case CONTENT_TYPE_AUDIO:
480 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
481 makeThumbnail = false;
482 pTempBitmap = pAppResource->GetBitmapN(IDB_MUSIC, pixelFormat);
486 case CONTENT_TYPE_VIDEO:
488 makeThumbnail = true;
493 case CONTENT_TYPE_OTHER:
495 makeThumbnail = false;
497 if (FilePath.EndsWith(L"pdf") || FilePath.EndsWith(L"PDF"))
499 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
500 pTempBitmap = pAppResource->GetBitmapN(IDB_PDF, pixelFormat);
503 else if (FilePath.EndsWith(L"doc") || FilePath.EndsWith(L"DOC"))
505 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
506 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_WORD, pixelFormat);
509 else if (FilePath.EndsWith(L"docx") || FilePath.EndsWith(L"DOCX"))
511 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
512 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_WORD, pixelFormat);
515 else if (FilePath.EndsWith(L"xls") || FilePath.EndsWith(L"XLS"))
517 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
518 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_EXCEL, pixelFormat);
521 else if (FilePath.EndsWith(L"xlsx") || FilePath.EndsWith(L"XLSX"))
523 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
524 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_EXCEL, pixelFormat);
527 else if (FilePath.EndsWith(L"ppt") || FilePath.EndsWith(L"PPT"))
529 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
530 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_PPT, pixelFormat);
533 else if (FilePath.EndsWith(L"pptx") || FilePath.EndsWith(L"PPTX"))
535 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
536 pTempBitmap = pAppResource->GetBitmapN(IDB_MS_PPT, pixelFormat);
539 else if (FilePath.EndsWith(L"html") || FilePath.EndsWith(L"HTML") || FilePath.EndsWith(L"htm") ||
540 FilePath.EndsWith(L"HTM") || FilePath.EndsWith(L"JS") || FilePath.EndsWith(L"js"))
542 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
543 pTempBitmap = pAppResource->GetBitmapN(IDB_HTML, pixelFormat);
546 else if (FilePath.EndsWith(L"rss") || FilePath.EndsWith(L"RSS"))
548 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
549 pTempBitmap = pAppResource->GetBitmapN(IDB_RSS, pixelFormat);
552 else if (FilePath.EndsWith(L"txt") || FilePath.EndsWith(L"TXT"))
554 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
555 pTempBitmap = pAppResource->GetBitmapN(IDB_TEXT, pixelFormat);
558 else if (FilePath.EndsWith(L"SVF") || FilePath.EndsWith(L"svg"))
560 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
561 pTempBitmap = pAppResource->GetBitmapN(IDB_SVG, pixelFormat);
564 else if (FilePath.EndsWith(L"swf") || FilePath.EndsWith(L"SWF"))
566 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
567 pTempBitmap = pAppResource->GetBitmapN(IDB_SWF, pixelFormat);
570 else if (FilePath.EndsWith(L"tpk") || FilePath.EndsWith(L"TPK") || FilePath.EndsWith(L"wgt") || FilePath.EndsWith(L"WGT"))
572 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
573 pTempBitmap = pAppResource->GetBitmapN(IDB_TPK, pixelFormat);
576 else if (FilePath.EndsWith(L"VCF") || FilePath.EndsWith(L"vcf"))
578 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
579 pTempBitmap = pAppResource->GetBitmapN(IDB_VCARD, pixelFormat);
582 else if (FilePath.EndsWith(L"vcs") || FilePath.EndsWith(L"VCS"))
584 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
585 pTempBitmap = pAppResource->GetBitmapN(IDB_VCALENDAR, pixelFormat);
590 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
591 pTempBitmap = pAppResource->GetBitmapN(IDB_UNKNOWN, pixelFormat);
596 case CONTENT_TYPE_UNKNOWN:
598 pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
599 makeThumbnail = false;
600 pTempBitmap = pAppResource->GetBitmapN(IDB_UNKNOWN, pixelFormat);
604 case CONTENT_TYPE_ALL:
606 //Empty Implementation
611 imageBuffer = new (std::nothrow) ImageBuffer();
612 TryCatch(imageBuffer != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Failed to allocate memory to imageBuffer");
614 r = imageBuffer->Construct(FilePath, null, true);
615 TryCatch(r == E_SUCCESS, thumbMgrRes = THUMB_MGR_RES_FAILED, "Failed to construct to image decoder");
617 pTempBitmap = imageBuffer->GetBitmapN(pixelFormat, BUFFER_SCALING_AUTO);
618 TryCatch(pTempBitmap != null, thumbMgrRes = THUMB_MGR_RES_FAILED, "Failed to decode bitmap");
620 if (imageBuffer != null)
625 AppLogDebug("EXIT: r = %s", GetErrorMessage(r));
629 makeThumbnail = false;
632 if (imageBuffer != null)
637 AppLogDebug("EXIT: Error Message [%s]", GetErrorMessage(r));
641 ThumbnailManager::SetThumbnailSize(void /*Tizen::Graphics::Dimension& dim*/)
647 Tizen::Graphics::Dimension&
648 ThumbnailManager::GetDefaultThumbSize(void)
654 ThumbnailManager::ClearCurrentThumbRequest(void)
656 result r = E_SUCCESS;
657 if (__pCurrentThumbReq)
659 __pCurrentThumbReq = null;
664 ThumbnailManager::OnUserEventReceivedN(RequestId requestId, Tizen::Base::Collection::IList* pArgs)
666 ThumbRequest* pTempThumbReq = null;
667 ArrayList* pTempArrayList = null;
668 result r = E_SUCCESS;
672 case ThumbnailManager::THUMB_MGR_GET_THUMBNAIL:
674 TryCatch(pArgs != null, r = E_FAILURE, "Argument list is null");
675 pTempThumbReq = (ThumbRequest*) pArgs->GetAt(0);
676 TryCatch(pTempThumbReq != null, r = E_FAILURE, "Request is null!");
678 __pCurrentThumbReq = pTempThumbReq;
679 TryCatch(__pCurrentThumbReq != null, , "E_FAILURE Current Request is null");
681 if (GetThumbnail(__pCurrentThumbReq) == THUMB_MGR_RES_SUCCESS)
683 pTempArrayList = new (std::nothrow) ArrayList();
684 pTempArrayList->Construct();
685 pTempArrayList->Add(pTempThumbReq);
686 Application::GetInstance()->SendUserEvent(THUMBNAIL_LAODED, pTempArrayList);
690 if (__pCurrentThumbReq != null)
692 if (__pCurrentThumbReq->pBitmap != null)
694 delete __pCurrentThumbReq->pBitmap;
695 __pCurrentThumbReq->pBitmap = null;
698 Application::GetInstance()->SendUserEvent(THUMBNAIL_FAILED, null);
703 case ThumbnailManager::THUMB_MGR_STOP:
705 ClearCurrentThumbRequest();
711 AppLogDebug("Unsupported case reached!");
712 Application::GetInstance()->SendUserEvent(THUMBNAIL_CANCELED, null);
718 ClearCurrentThumbRequest();
721 pArgs->RemoveAll(true);
724 Application::GetInstance()->SendUserEvent(THUMBNAIL_FAILED, null);
729 ThumbnailManager::StopThumbnailManagerThread(void)
731 result r = E_SUCCESS;
734 AppLogDebug("Exit : %s", GetErrorMessage(r));