2 // Open Service Platform
3 // Copyright (c) 2012-2013 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.
19 * @file FApp_AppResourceBitmapUtil.cpp
20 * @brief This is the implementation for the _AppResourceBitmapUtil class.
23 #include <unique_ptr.h>
25 #include <FAppPkgPackageManager.h>
26 #include <FAppPkgPackageInfo.h>
27 #include <FBaseSysLog.h>
28 #include <FBaseByteBuffer.h>
29 #include <FMediaImageTypes.h>
30 #include <FMedia_ImageDecoder.h>
31 #include <FSys_SystemInfoImpl.h>
32 #include <FUi_ControlManager.h>
33 #include "FAppPkg_PackageInfoImpl.h"
34 #include "FApp_AppInfo.h"
35 #include "FApp_AppResourceBitmapUtil.h"
38 using namespace Tizen::App::Package;
39 using namespace Tizen::Base;
40 using namespace Tizen::Graphics;
41 using namespace Tizen::Io;
42 using namespace Tizen::Media;
43 using namespace Tizen::Ui;
48 ConvertBitmapPixelFormatToMediaPixelFormat(BitmapPixelFormat format)
50 MediaPixelFormat out = MEDIA_PIXEL_FORMAT_NONE;
53 case BITMAP_PIXEL_FORMAT_RGB565:
54 out = MEDIA_PIXEL_FORMAT_RGB565LE;
56 case BITMAP_PIXEL_FORMAT_ARGB8888:
57 out = MEDIA_PIXEL_FORMAT_BGRA8888;
59 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
60 out = MEDIA_PIXEL_FORMAT_RGBA8888;
66 }} // unnamed namespace
68 namespace Tizen { namespace Graphics
71 _CreateCoordinateTransformer(_ICoordinateSystemTransformer*& pTransformer, int srcResolution, _BaseScreenSize srcBaseScreenSize, Dimension destResolution, _BaseScreenSize destBaseScreenSize);
74 namespace Tizen { namespace App
77 _AppResourceBitmapUtil::_AppResourceBitmapUtil(void)
78 : __physicalResolutionDim(0, 0)
79 , __physicalBaseScreenSize(BASE_SCREEN_SIZE_DEFAULT)
80 , __resolutionDirectories(L"")
81 , __sortedDensityDirectories()
83 for (int i = 0; i < DENSITY_MAX; i++)
85 __sortedDensity[i] = DENSITY_NONE;
87 __physicalResolutionDim = _CoordinateSystem::GetInstance()->GetPhysicalResolutionDim();
88 __physicalBaseScreenSize = _CoordinateSystem::GetInstance()->GetPhysicalBaseScreenSize();
91 _AppResourceBitmapUtil::~_AppResourceBitmapUtil(void)
96 _AppResourceBitmapUtil::Construct(void)
99 result r = Tizen::System::_SystemInfoImpl::GetSysInfo(L"http://tizen.org/feature/screen.dpi", deviceDPI);
100 SysTryReturnResult(NID_APP, r == E_SUCCESS, r, "[%s] Failed to get Screen DPI", GetErrorMessage(r));
102 // 1. Get directory path matched device's resolution (e.g.720x1280)
103 if (GetDirectoryPath(DENSITY_NONE, __resolutionDirectories) == false)
105 __resolutionDirectories = L"";
106 SysLog(NID_APP, "Failed to get a Device Resolution Directory path");
109 // 2. Get screen density & directory path matched device's DPI (e.g.screen-density-xhigh)
110 if (deviceDPI >= DPI_FOR_XHIGH)
112 __sortedDensity[0] = DENSITY_XHIGH;
114 else if (deviceDPI >= DPI_FOR_HIGH)
116 __sortedDensity[0] = DENSITY_HIGH;
118 else if (deviceDPI >= DPI_FOR_MIDDLE)
120 __sortedDensity[0] = DENSITY_MIDDLE;
122 else if (deviceDPI < DPI_FOR_MIDDLE && deviceDPI >= DPI_FOR_LOW)
124 __sortedDensity[0] = DENSITY_LOW;
128 __sortedDensity[0] = DENSITY_XHIGH;
129 SysLog(NID_APP, "Failed to get a Device Density (DPI = %d)", deviceDPI);
132 if (GetDirectoryPath(__sortedDensity[0], __sortedDensityDirectories[0]) == false)
134 __sortedDensityDirectories[0] = L"";
135 SysLog(NID_APP, "Failed to get a Device Density Directory path");
138 // 3. Get screen density & directory path with fall back system (XHIGH-HIGH-MIDDLE-LOW)
139 int densityIndex = 1;
141 for (int currentDensity = DENSITY_XHIGH; currentDensity >= DENSITY_LOW; currentDensity--)
143 SysAssert(densityIndex > DENSITY_NONE && densityIndex < DENSITY_MAX);
145 if (static_cast<int>(__sortedDensity[0]) == currentDensity)
150 __sortedDensity[densityIndex] = static_cast<_Density>(currentDensity);
152 if (GetDirectoryPath(__sortedDensity[densityIndex], __sortedDensityDirectories[densityIndex]) == false)
154 __sortedDensityDirectories[densityIndex] = L"";
155 SysLog(NID_APP, "Failed to get a %dth Fall-Back Directory path", densityIndex);
165 _AppResourceBitmapUtil::Construct(const String& appId)
168 result r = Tizen::System::_SystemInfoImpl::GetSysInfo(L"http://tizen.org/feature/screen.dpi", deviceDPI);
169 SysTryReturnResult(NID_APP, r == E_SUCCESS, r, "[%s] Failed to get Screen DPI", GetErrorMessage(r));
171 // 1. Get directory path matched device's resolution (e.g.720x1280)
172 if (GetDirectoryPath(DENSITY_NONE, __resolutionDirectories, appId) == false)
174 __resolutionDirectories = L"";
175 SysLog(NID_APP, "Failed to get a Device Resolution Directory path");
178 // 2. Get screen density & directory path matched device's DPI (e.g.screen-density-xhigh)
179 if (deviceDPI >= DPI_FOR_XHIGH)
181 __sortedDensity[0] = DENSITY_XHIGH;
183 else if (deviceDPI >= DPI_FOR_HIGH)
185 __sortedDensity[0] = DENSITY_HIGH;
187 else if (deviceDPI >= DPI_FOR_MIDDLE)
189 __sortedDensity[0] = DENSITY_MIDDLE;
191 else if (deviceDPI < DPI_FOR_MIDDLE && deviceDPI >= DPI_FOR_LOW)
193 __sortedDensity[0] = DENSITY_LOW;
197 __sortedDensity[0] = DENSITY_XHIGH;
198 SysLog(NID_APP, "Failed to get a Device Density (DPI = %d)", deviceDPI);
201 if (GetDirectoryPath(__sortedDensity[0], __sortedDensityDirectories[0], appId) == false)
203 __sortedDensityDirectories[0] = L"";
204 SysLog(NID_APP, "Failed to get a Device Density Directory path");
207 // 3. Get screen density & directory path with fall back system (XHIGH-HIGH-MIDDLE-LOW)
208 int densityIndex = 1;
210 for (int currentDensity = DENSITY_XHIGH; currentDensity >= DENSITY_LOW; currentDensity--)
212 SysAssert(densityIndex > DENSITY_NONE && densityIndex < DENSITY_MAX);
214 if (static_cast<int>(__sortedDensity[0]) == currentDensity)
219 __sortedDensity[densityIndex] = static_cast<_Density>(currentDensity);
221 if (GetDirectoryPath(__sortedDensity[densityIndex], __sortedDensityDirectories[densityIndex], appId) == false)
223 __sortedDensityDirectories[densityIndex] = L"";
224 SysLog(NID_APP, "Failed to get a %dth Fall-Back Directory path", densityIndex);
233 // Get Resource DirectoryPath
235 _AppResourceBitmapUtil::GetDirectoryPath(const _Density resourceDirectory, String& dirPath) const
237 const String& homePath(_AppInfo::GetAppRootPath() + L"res/");
239 switch (resourceDirectory)
242 switch (__physicalResolutionDim.width)
245 dirPath = L"720x1280";
249 dirPath = L"480x800";
253 dirPath = L"240x400";
257 dirPath = L"320x480";
266 dirPath = L"screen-density-xhigh";
270 dirPath = L"screen-density-high";
274 dirPath = L"screen-density-middle";
278 dirPath = L"screen-density-low";
286 result r = dirPath.Insert(homePath, 0);
287 SysTryReturn(NID_APP, r == E_SUCCESS, false, r, "[%s] Failed to insert string.", GetErrorMessage(r));
289 if ( File::IsFileExist(dirPath) == false )
298 _AppResourceBitmapUtil::GetDirectoryPath(const _Density resourceDirectory, String& dirPath, const String& appId) const
300 PackageInfo* pPkgInfo = null;
301 pPkgInfo = _PackageManagerImpl::GetInstance()->GetPackageInfoN(appId);
302 _PackageInfoImpl* pPkgInfoImpl = _PackageInfoImpl::GetInstance(pPkgInfo);
303 SysTryReturn(NID_APP, pPkgInfoImpl != null, false, E_APP_NOT_INSTALLED, "[E_APP_NOT_INSTALLED] Failed to create the package info instance");
305 const String& homePath(pPkgInfoImpl->GetAppRootPath() + L"/res/");
309 switch (resourceDirectory)
312 switch (__physicalResolutionDim.width)
315 dirPath = L"720x1280";
319 dirPath = L"480x800";
323 dirPath = L"240x400";
327 dirPath = L"320x480";
336 dirPath = L"screen-density-xhigh";
340 dirPath = L"screen-density-high";
344 dirPath = L"screen-density-middle";
348 dirPath = L"screen-density-low";
356 result r = dirPath.Insert(homePath, 0);
357 SysTryReturn(NID_APP, r == E_SUCCESS, false, r, "[%s] Failed to insert string.", GetErrorMessage(r));
359 if ( File::IsFileExist(dirPath) == false )
367 // Get Resource File Path
369 _AppResourceBitmapUtil::GetFilePath(const String& directoryPath, const String& fileName, String& filePath) const
371 if (directoryPath == null)
377 const String& normalizedPseudoPath = NormalizePath(fileName);
378 SysAssert(normalizedPseudoPath.StartsWith(L"/", 0));
380 filePath = directoryPath + normalizedPseudoPath;
387 _AppResourceBitmapUtil::NormalizePath(const String& path) const
389 String normalizedPath = path;
391 normalizedPath.Replace(L'\\', L'/');
393 if (normalizedPath.StartsWith(L"/", 0) == false)
395 result r = normalizedPath.Insert(L'/', 0);
396 SysTryLog(NID_APP, r == E_SUCCESS, "[%s] Propagating.", GetErrorMessage(r));
399 return normalizedPath;
402 // Get Matched Resource File Path
404 _AppResourceBitmapUtil::GetResourcePath(const String& fileName, String& resourcePath, _Density& resourceDensity, bool& imageScaling) const
406 result r = E_SUCCESS;
408 // 1. Try to search resolution Folder
409 String resourcePathForResolution(L"");
411 if (__resolutionDirectories.IsEmpty() == false &&
412 GetFilePath(__resolutionDirectories, fileName, resourcePathForResolution))
414 if (File::IsFileExist(resourcePathForResolution))
416 resourcePath = resourcePathForResolution;
417 resourceDensity = DENSITY_NONE;
418 imageScaling = false;
425 // 2. Try to search resource directory matched device's DPI
426 String resourcePathForDensity(L"");
428 if (__sortedDensityDirectories[0].IsEmpty() == false &&
429 GetFilePath(__sortedDensityDirectories[0], fileName, resourcePathForDensity))
431 if (File::IsFileExist(resourcePathForDensity))
433 resourcePath = resourcePathForDensity;
434 resourceDensity = __sortedDensity[0];
435 imageScaling = _CoordinateSystem::GetInstance()->IsTransformEnabled();
442 // 3. Try to find the alternative path with fall back
443 int fallbackIndex = 1;
444 String alternativeResourcePath(L"");
446 for (int findingDensity = DENSITY_XHIGH; findingDensity > DENSITY_LOW; findingDensity--)
448 if (__sortedDensityDirectories[fallbackIndex].IsEmpty() == false &&
449 GetFilePath(__sortedDensityDirectories[fallbackIndex], fileName, alternativeResourcePath))
451 if (File::IsFileExist(alternativeResourcePath))
453 resourcePath = alternativeResourcePath;
454 resourceDensity = __sortedDensity[fallbackIndex];
464 SysTryReturn(NID_APP, r == E_SUCCESS, E_FILE_NOT_FOUND, E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] The specified file cannot be found.");
470 _AppResourceBitmapUtil::GetBitmapN(const String& resourcePath, const _Density resourceDensity,
471 BitmapPixelFormat pixelFormat, bool imageScaling, const Color* pChromaKeyColor) const
474 SysTryReturn(NID_APP, (pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX), null,
475 E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] The image file format or specified pixel format(%d) is not supported.", pixelFormat);
477 result r = E_SUCCESS;
479 unique_ptr<Bitmap> pBitmap;
481 if (!pChromaKeyColor && imageScaling == false) // NonScaling
483 pBitmap.reset(new (std::nothrow) Bitmap());
484 SysTryReturn(NID_APP, pBitmap != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
486 r = _BitmapImpl::GetInstance(*pBitmap)->Construct(resourcePath, pixelFormat);
487 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
489 return pBitmap.release();
493 MediaPixelFormat format = ConvertBitmapPixelFormatToMediaPixelFormat(pixelFormat);
497 std::unique_ptr<ByteBuffer> pBuffer(_ImageDecoder::DecodeToBufferN(resourcePath, format, imageWidth, imageHeight));
499 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
500 SysTryReturn(NID_APP, pBuffer != null, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
502 pBitmap.reset(_BitmapImpl::GetNonScaledBitmapN(*pBuffer, Dimension(imageWidth, imageHeight), pixelFormat));
504 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
505 SysTryReturn(NID_APP, pBitmap != null, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
507 int resourceLogicalCoordinate = __physicalResolutionDim.width;
509 switch (resourceDensity)
512 resourceLogicalCoordinate = 720;
516 resourceLogicalCoordinate = 480;
520 resourceLogicalCoordinate = 320;
524 resourceLogicalCoordinate = 240;
531 _ICoordinateSystemTransformer* pTempXformer(null);
532 r = _CreateCoordinateTransformer(pTempXformer,
533 resourceLogicalCoordinate, __physicalBaseScreenSize,
534 Dimension(_CoordinateSystem::GetInstance()->GetLogicalResolutionInt(), _CoordinateSystem::GetInstance()->GetLogicalResolutionInt()), _CoordinateSystem::GetInstance()->GetLogicalBaseScreenSize());
536 std::unique_ptr<_ICoordinateSystemTransformer> pXformer(pTempXformer);
537 SysTryReturn(NID_APP, pXformer != null, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
538 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
540 Dimension baseImageSize = pXformer->Transform(Dimension(imageWidth, imageHeight));
542 SysTryReturn(NID_APP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
544 r = pBitmap->Scale(baseImageSize);
545 SysTryReturn(NID_APP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] A system error has occurred.");
548 if (pChromaKeyColor != null)
550 r = pBitmap->SetMaskingColor(pChromaKeyColor);
551 SysTryReturn(NID_APP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
554 SetLastResult(E_SUCCESS);
556 return pBitmap.release();