add patch
[framework/osp/uifw.git] / src / graphics / FGrp_BitmapImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
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
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0/
10 //
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.
16 //
17
18 /*
19  * @file        FGrp_BitmapImpl.cpp
20  * @brief       This is the implementation file for _BitmapImpl class.
21  *
22  */
23
24 #include <new>
25 #include <memory>
26 #include <utility>
27
28 #include <FBaseSysLog.h>
29 #include <FIoFile.h>
30
31 #include <FGrpBitmap.h>
32
33 #include <FMedia_ImageDecoder.h>
34
35 #include "FGrp_BitmapImpl.h"
36 #include "FGrp_BitmapUtil.h"
37 #include "FGrp_BitmapCoordHolder.h"
38 #include "FGrp_Bitmap.h"
39 #include "FGrp_Canvas.h"
40 #include "FGrp_NonScale.h"
41 #include "FGrp_ResUtil.h"
42 #include "util/FGrp_Util.h"
43 #include "effect/FGrp_Effect.h"
44 #include "effect/FGrp_EffectFunc.h"
45
46 using namespace Tizen::Base;
47
48 #define INSTANCE_IS_VALID (this && const_cast<_BitmapImpl*>(this)->__CheckValidity(true))
49 #define IS_INSTANCE_VALID (this && const_cast<_BitmapImpl*>(this)->__CheckValidity(false))
50
51 #define BITMAPIMPL_IS_VALID(pBitmapImpl) (pBitmapImpl && const_cast<_BitmapImpl*>(pBitmapImpl)->__CheckValidity(true))
52 #define IS_BITMAPIMPL_VALID(pBitmapImpl) (pBitmapImpl && const_cast<_BitmapImpl*>(pBitmapImpl)->__CheckValidity(false))
53
54
55 namespace // unnamed
56 {
57
58 bool
59 _CheckValidityOfRectangle(const Tizen::Graphics::Rectangle& rect)
60 {
61         return ((rect.width > 0) && (rect.height > 0));
62 }
63
64 bool
65 _CheckValidity(const Tizen::Graphics::Rectangle& rtSrc, const Tizen::Graphics::Rectangle& rtDest)
66 {
67         // check 1. is width/height less or equal than 0?
68         if (rtSrc.width <= 0 || rtSrc.height <= 0 || rtDest.width <= 0 || rtDest.height <= 0)
69         {
70                 return false;     // "[E_OUT_OF_RANGE] The argument is out of range. (src(w:%d,h:%d), dst(w:%d,h:%d))", rtSrc.width, rtSrc.height, rtDest.width, rtDest.height);
71         }
72
73         // check 2.     is src exiting outside of dest entirely?
74         if (rtSrc.x > rtDest.x + rtDest.width - 1 || rtSrc.x + rtSrc.width - 1 < rtDest.x)
75         {
76                 return false;     // "[E_OUT_OF_RANGE] The argument is out of range. (src(x:%d,y:%d,w:%d,h:%d), dst(x:%d,y:%d,w:%d,h:%d))", rtSrc.x, rtSrc.y, rtSrc.width, rtSrc.height, rtDest.x, rtDest.y, rtDest.width, rtDest.height);
77         }
78
79         if (rtSrc.y > rtDest.y + rtDest.height - 1 || rtSrc.y + rtSrc.height - 1 < rtDest.y)
80         {
81                 return false;     // "[E_OUT_OF_RANGE] The argument is out of range. (src(x:%d,y:%d,w:%d,h:%d), dst(x:%d,y:%d,w:%d,h:%d))", rtSrc.x, rtSrc.y, rtSrc.width, rtSrc.height, rtDest.x, rtDest.y, rtDest.width, rtDest.height);
82         }
83
84         return true;
85 }
86
87 bool
88 _CheckValidity(const Tizen::Graphics::FloatRectangle& rtSrc, const Tizen::Graphics::FloatRectangle& rtDest)
89 {
90         // check 1. is width/height less or equal than 0?
91         if (rtSrc.width <= 0.0f || rtSrc.height <= 0.0f || rtDest.width <= 0.0f || rtDest.height <= 0.0f)
92         {
93                 return false;     // "[E_OUT_OF_RANGE] The argument is out of range. (src(w:%f,h:%f), dst(w:%f,h:%f))", rtSrc.width, rtSrc.height, rtDest.width, rtDest.height);
94         }
95
96         // check 2.     is src exiting outside of dest entirely?
97         if (rtSrc.x > rtDest.x + rtDest.width || rtSrc.x + rtSrc.width < rtDest.x)
98         {
99                 return false;     // "[E_OUT_OF_RANGE] The argument is out of range. (src(x:%f,y:%f,w:%f,h:%f), dst(x:%f,y:%f,w:%f,h:%f))", rtSrc.x, rtSrc.y, rtSrc.width, rtSrc.height, rtDest.x, rtDest.y, rtDest.width, rtDest.height);
100         }
101
102         if (rtSrc.y > rtDest.y + rtDest.height || rtSrc.y + rtSrc.height < rtDest.y)
103         {
104                 return false;     // "[E_OUT_OF_RANGE] The argument is out of range. (src(x:%f,y:%f,w:%f,h:%f), dst(x:%f,y:%f,w:%f,h:%f))", rtSrc.x, rtSrc.y, rtSrc.width, rtSrc.height, rtDest.x, rtDest.y, rtDest.width, rtDest.height);
105         }
106
107         return true;
108 }
109
110
111 int
112 _GetBytesPerPixel(Tizen::Graphics::BitmapPixelFormat pixelFormat)
113 {
114         if (pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565)
115         {
116                 return 2;
117         }
118         else if (pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888 || pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8)
119         {
120                 return 4;
121         }
122         else
123         {
124                 return 0;
125         }
126 }
127
128 void
129 _GetScaleInfo(Tizen::Graphics::BitmapScalingQuality quality, float width, float height, float scaleWidth, float scaleHeight, Tizen::Graphics::_Util::AccumList<Tizen::Graphics::_Util::Pair<float, float> >& scalingValue)
130 {
131         scalingValue.Clear();
132
133         scalingValue.Push(Tizen::Graphics::_Util::MakePair(scaleWidth, scaleHeight));
134
135         if (quality == Tizen::Graphics::BITMAP_SCALING_QUALITY_HIGH)
136         {
137                 int intWidth = int(width);
138                 int intHeight = int(height);
139
140                 int tempWidth = int(scaleWidth);
141                 int tempHeight = int(scaleHeight);
142
143                 while (intWidth > (tempWidth << 1) || intHeight > (tempHeight << 1))
144                 {
145                         if (intWidth > (tempWidth << 1))
146                         {
147                                 tempWidth <<= 1;
148                         }
149
150                         if (intHeight > (tempHeight << 1))
151                         {
152                                 tempHeight <<= 1;
153                         }
154
155                         scalingValue.Push(Tizen::Graphics::_Util::MakePair(float(tempWidth), float(tempHeight)));
156                 }
157         }
158 }
159
160
161 result
162 _CheckBufferSize(const Tizen::Base::ByteBuffer& buffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat pixelFormat)
163 {
164         int bytePerPixel = _GetBytesPerPixel(pixelFormat);
165
166         if (bytePerPixel == 0)
167         {
168                 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
169         }
170
171         int byteNum = buffer.GetLimit();
172         int expectedBufferSize = dim.width * dim.height * bytePerPixel;
173
174         SysTryReturnResult(NID_GRP, expectedBufferSize <= byteNum, E_INVALID_ARG, "A buffer size is not correct. (expected: %d, actual: %d)", expectedBufferSize, byteNum);
175
176         return E_SUCCESS;
177 }
178
179 bool
180 _ScaleBuffer(const Tizen::Base::ByteBuffer& destBuffer, const Tizen::Graphics::Dimension& destSize, const Tizen::Base::ByteBuffer& sourBuffer, const Tizen::Graphics::Dimension& sourSize, Tizen::Graphics::BitmapPixelFormat pixelFormat)
181 {
182         switch (pixelFormat)
183         {
184         case Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565:
185         {
186                 Tizen::Graphics::_Util::Pixmap dstImage(destSize.width, destSize.height, 16, (void*) destBuffer.GetPointer());
187                 Tizen::Graphics::_Util::Pixmap srcImage(sourSize.width, sourSize.height, 16, (void*) sourBuffer.GetPointer());
188                 return Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, destSize.width, destSize.height, srcImage);
189         }
190         case Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888:
191         {
192                 Tizen::Graphics::_Util::Pixmap dstImage(destSize.width, destSize.height, 32, (void*) destBuffer.GetPointer());
193                 Tizen::Graphics::_Util::Pixmap srcImage(sourSize.width, sourSize.height, 32, (void*) sourBuffer.GetPointer());
194                 return Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, destSize.width, destSize.height, srcImage);
195         }
196         case Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8:
197                 return false;
198         default:
199                 return false;
200         }
201 }
202
203 bool
204 _UpdateScaledBitmapEx(Tizen::Graphics::_Bitmap* pSrcBitmap, Tizen::Graphics::_Bitmap* pDstBitmap)
205 {
206         if (!(pSrcBitmap && pDstBitmap && pSrcBitmap->GetPixelColorFormat() == pDstBitmap->GetPixelColorFormat()))
207         {
208                 return false;
209         }
210
211         Tizen::Graphics::BufferInfo srcBufferInfo;
212         Tizen::Graphics::BufferInfo dstBufferInfo;
213
214         {
215                 if (pSrcBitmap->Lock(srcBufferInfo) != E_SUCCESS)
216                 {
217                         return false;
218                 }
219
220                 result r = pDstBitmap->Lock(dstBufferInfo);
221                 if (r != E_SUCCESS)
222                 {
223                         pSrcBitmap->Unlock();
224                         return false;
225                 }
226         }
227
228         bool ret = false;
229
230         do
231         {
232                 switch (pSrcBitmap->GetPixelColorFormat())
233                 {
234                 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565:
235                 {
236                         Tizen::Graphics::_Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, 16, (void*) dstBufferInfo.pPixels);
237                         Tizen::Graphics::_Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, 16, (void*) srcBufferInfo.pPixels);
238                         ret = Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, dstBufferInfo.width, dstBufferInfo.height, srcImage);
239                 }
240                 break;
241
242                 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888:
243                 {
244                         Tizen::Graphics::_Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, 32, (void*) dstBufferInfo.pPixels);
245                         Tizen::Graphics::_Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, 32, (void*) srcBufferInfo.pPixels);
246                         ret = Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, dstBufferInfo.width, dstBufferInfo.height, srcImage);
247                 }
248                 break;
249
250                 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8:
251                 default:
252                         break;
253                 }
254         }
255         while (0);
256
257         pSrcBitmap->Unlock();
258         pDstBitmap->Unlock();
259
260         return ret;
261 }
262
263 ////////////////////////////////////////////////////////////////////////////////
264
265 unsigned long
266 _UpdateBitmapTimeStampInternal(void)
267 {
268         static unsigned long staticTimeStamp = 0;
269
270         ++staticTimeStamp;
271
272         staticTimeStamp = (staticTimeStamp == 0) ? (staticTimeStamp + 1) : staticTimeStamp;
273
274         return staticTimeStamp;
275 }
276
277 }
278
279 ////////////////////////////////////////////////////////////////////////////////
280
281 namespace Tizen { namespace Graphics
282 {
283
284 unsigned long
285 _GetBitmapTimeStamp(const Tizen::Graphics::_BitmapImpl& bitmap)
286 {
287         Tizen::Graphics::_Bitmap* _nativeBitmap = Tizen::Graphics::_GetBitmapEx(bitmap);
288
289         return (_nativeBitmap) ? _nativeBitmap->GetTimeStamp() : 0;
290 }
291
292 unsigned long
293 _UpdateBitmapTimeStamp(Tizen::Graphics::_BitmapImpl& bitmap)
294 {
295         Tizen::Graphics::_Bitmap* _nativeBitmap = Tizen::Graphics::_GetBitmapEx(bitmap);
296
297         if (_nativeBitmap)
298         {
299                 _nativeBitmap->SetTimeStamp(_UpdateBitmapTimeStampInternal());
300                 return _nativeBitmap->GetTimeStamp();
301         }
302
303         return 0;
304 }
305
306 ////////////////////////////////////////////////////////////////////////////////
307
308 _BitmapImpl::_BitmapImpl(void)
309         : _magicKey(0)
310         , _sharedItem(std::tr1::shared_ptr<_SharedItem>(new (std::nothrow)_SharedItem))
311 {
312         if (this->_sharedItem.get())
313         {
314                 this->_sharedItem->nativeBitmap.reset(new (std::nothrow) _Bitmap);
315                 this->_sharedItem->coordHolder.reset(new (std::nothrow) _BitmapCoordinateHolder);
316                 this->_sharedItem->lazyScaling = 0;
317                 this->_sharedItem->scaledNativeBitmap.reset(null);
318                 this->_sharedItem->pDestroyCallbackFunc = null;
319                 this->_sharedItem->pDestroyCallbackParam = null;
320                 this->_sharedItem->pLockCallbackFunc = null;
321                 this->_sharedItem->pLockCallbackParam = null;
322                 this->_sharedItem->pUnlockCallbackFunc = null;
323                 this->_sharedItem->pUnlockCallbackParam = null;
324                 this->_sharedItem->isMutable = true;
325                 this->_sharedItem->associated.pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
326                 this->_sharedItem->associated.hasBeenDetectedByUsingName = false;
327                 this->_sharedItem->associated.determinedNinePatchedAtFirst = false;
328
329                 if (this->_sharedItem->nativeBitmap.get() == null || this->_sharedItem->coordHolder.get() == null)
330                 {
331                         this->_sharedItem->nativeBitmap.reset();
332                         this->_sharedItem->coordHolder.reset();
333                         this->_sharedItem.reset();
334
335                         return;
336                 }
337         }
338
339         _UpdateBitmapTimeStamp(*this);
340
341         _Util::CarveMagicKey(*this, _magicKey);
342 }
343
344 _BitmapImpl::~_BitmapImpl(void)
345 {
346         if (this->_sharedItem.get())
347         {
348                 if (this->_sharedItem->pDestroyCallbackFunc)
349                 {
350                         if (this->_sharedItem.unique())
351                         {
352                                 this->_sharedItem->pDestroyCallbackFunc(this->_sharedItem->pDestroyCallbackParam);
353                         }
354                 }
355         }
356
357         _Util::EraseMagicKey(*this, _magicKey);
358 }
359
360 bool
361 _BitmapImpl::IsConstructed(void) const
362 {
363         return (this->_sharedItem.get() && (this->_sharedItem->nativeBitmap->IsValid() || !this->_sharedItem->associated.fileName.IsEmpty()));
364 }
365
366 Tizen::Base::String
367 _BitmapImpl::GetFileName(void) const
368 {
369         return (this->_sharedItem.get()) ? this->_sharedItem->associated.fileName : String();
370 }
371
372 result
373 _BitmapImpl::Construct(const Rectangle& vc_rect)
374 {
375         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
376
377         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
378
379         SysTryReturnResult(NID_GRP, _CheckValidityOfRectangle(vc_rect), E_INVALID_ARG, "Both of width(%d) and height(%d) of 'rect' MUST be greater than 0.", vc_rect.width, vc_rect.height);
380
381         SysTryReturnResult(NID_GRP, vc_rect.x >= 0 && vc_rect.y >= 0, E_OUT_OF_RANGE, "The argument is out of range. (rect(x:%d,y:%d,w:%d,h:%d)).", vc_rect.x, vc_rect.y, vc_rect.width, vc_rect.height);
382
383         {
384                 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
385
386                 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
387
388                 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
389
390                 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
391
392                 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
393                 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
394
395                 return this->_sharedItem->nativeBitmap->Construct(pcRect);
396         }
397 }
398
399 result
400 _BitmapImpl::Construct(const Dimension& vc_dim, BitmapPixelFormat pixelFormat)
401 {
402         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
403
404         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
405
406         // check arg.
407         SysTryReturnResult(NID_GRP, vc_dim.width > 0 && vc_dim.height > 0, E_INVALID_ARG, "Both of width(%d) and height(%d) of 'dim' MUST be greater than 0.", vc_dim.width, vc_dim.height);
408
409         switch (pixelFormat)
410         {
411         case BITMAP_PIXEL_FORMAT_RGB565:
412         case BITMAP_PIXEL_FORMAT_ARGB8888:
413         case BITMAP_PIXEL_FORMAT_R8G8B8A8:
414                 break;
415         default:
416                 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
417                 break;
418         }
419
420         {
421                 _Util::Dimension<int> vcDim = { vc_dim.width, vc_dim.height };
422
423                 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
424
425                 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
426
427                 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
428
429                 return this->_sharedItem->nativeBitmap->Construct(pcDim, pixelFormat);
430         }
431 }
432
433 result
434 _BitmapImpl::Construct(const _CanvasImpl& canvas, const Rectangle& vc_rect)
435 {
436         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
437
438         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
439
440         SysTryReturnResult(NID_GRP, &canvas, E_INVALID_ARG, "A canvas is invalid.");
441         SysTryReturnResult(NID_GRP, canvas._pNativeCanvas && canvas._pNativeCanvas->IsValid(), E_INVALID_ARG, "A canvas is invalid.");
442
443         Rectangle rtCanvas = canvas.GetBounds();
444
445         SysTryReturnResult(NID_GRP, !rtCanvas.IsEmpty(), E_INVALID_ARG, "A canvas is empty.");
446
447         SysTryReturnResult(NID_GRP, _CheckValidityOfRectangle(vc_rect), E_INVALID_ARG, "Both of width(%d) and height(%d) of 'rect' MUST be greater than 0.", vc_rect.width, vc_rect.height);
448
449         SysTryReturnResult(NID_GRP, _CheckValidity(vc_rect, rtCanvas), E_OUT_OF_RANGE, "The argument is out of range. (rect(x:%d,y:%d,w:%d,h:%d)).", vc_rect.x, vc_rect.y, vc_rect.width, vc_rect.height);
450
451         Tizen::Graphics::_Canvas* pCanvasEx = canvas._pNativeCanvas;
452
453         {
454                 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
455
456                 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
457
458                 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
459
460                 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
461
462                 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
463                 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
464
465                 return this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, pcRect);
466         }
467 }
468
469 result
470 _BitmapImpl::Construct(const _BitmapImpl& bitmap, const Rectangle& vc_rect)
471 {
472         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
473
474         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
475
476         SysTryReturnResult(NID_GRP, BITMAPIMPL_IS_VALID(&bitmap), E_INVALID_ARG, "The source bitmap is invalid.");
477
478         Rectangle rtBitmap(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
479
480         SysTryReturnResult(NID_GRP, _CheckValidityOfRectangle(vc_rect), E_INVALID_ARG, "Both of width(%d) and height(%d) of 'rect' MUST be greater than 0.", vc_rect.width, vc_rect.height);
481
482         SysTryReturnResult(NID_GRP, _CheckValidity(vc_rect, rtBitmap), E_OUT_OF_RANGE, "The argument is out of range. (rect(x:%d,y:%d,w:%d,h:%d)).", vc_rect.x, vc_rect.y, vc_rect.width, vc_rect.height);
483
484         _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(bitmap);
485
486         {
487                 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
488
489                 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
490
491                 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
492
493                 result r = E_SUCCESS;
494                 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
495
496                 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
497                 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
498
499                 if (Tizen::Graphics::_IsLazyScalingBitmap(bitmap))
500                 {
501                         _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(bitmap);
502
503                         r = this->_sharedItem->nativeBitmap->Construct(*pSrcScaledBitmapEx, pcRect);
504                 }
505                 else
506                 {
507                         r = this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, pcRect);
508                 }
509
510                 return r;
511         }
512 }
513
514 result
515 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat)
516 {
517 #if 1
518         return this->Construct(buffer, rq_dim, pixelFormat, true);
519 #else
520 //      return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_AUTO);
521 //      return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_NONE);
522
523         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
524
525         SysTryReturnResult(NID_GRP, __pImpl && this->_nativeBitmap, E_OUT_OF_MEMORY, "Fails to allocate memory.");
526
527         SysTryReturnResult(NID_GRP, rq_dim.width > 0 && rq_dim.height > 0, E_INVALID_ARG, "Both of width(%d) and height(%d) of a dimension MUST be greater than 0.", rq_dim.width, rq_dim.height);
528
529         SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
530
531         {
532                 // buffer size should be verified.
533                 int bytePerPixel = 0;
534                 if (BITMAP_PIXEL_FORMAT_RGB565 == pixelFormat)
535                 {
536                         bytePerPixel = 2;
537                 }
538                 else if (BITMAP_PIXEL_FORMAT_ARGB8888 == pixelFormat || BITMAP_PIXEL_FORMAT_R8G8B8A8 == pixelFormat)
539                 {
540                         bytePerPixel = 4;
541                 }
542                 else
543                 {
544                         SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
545                 }
546
547                 int byteNum = buffer.GetLimit();
548                 int expectedBufferSize = rq_dim.width * rq_dim.height * bytePerPixel;
549
550                 SysTryReturnResult(NID_GRP, expectedBufferSize <= byteNum, E_INVALID_ARG, "A buffer size is not correct.");
551         }
552
553         if (_ResUtil::NeedToConvertCoord())
554         {
555                 Dimension vc_dim;
556                 Dimension pc_dim;
557
558                 vc_dim = rq_dim;
559                 pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
560
561                 // special case
562                 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
563                 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
564
565                 if (pc_dim.width * 2 == rq_dim.width && pc_dim.height * 2 == rq_dim.height)
566                 {
567                         int pitch = rq_dim.width;
568
569                         if (pixelFormat == BITMAP_PIXEL_FORMAT_ARGB8888)
570                         {
571                                 const unsigned long MASK = 0x00FF00FF;
572
573                                 unsigned long* pBuffer = (unsigned long*) buffer.GetPointer();
574                                 for (int y = 0; y < pc_dim.height; y++)
575                                 {
576                                         for (int x = 0; x < pc_dim.width; x++)
577                                         {
578                                                 unsigned long add1 = (pBuffer[0] & MASK) + (pBuffer[1] & MASK) + (pBuffer[pitch] & MASK) + (pBuffer[pitch + 1] & MASK);
579                                                 unsigned long add2 = ((pBuffer[0] >> 8) & MASK) + ((pBuffer[1] >> 8) & MASK) + ((pBuffer[pitch] >> 8) & MASK) + ((pBuffer[pitch + 1] >> 8) & MASK);
580
581                                                 unsigned long pix = ((add1 >> 2) & MASK) | (((add2 >> 2) & MASK) << 8);
582
583                                                 pBuffer[0] = pix;
584                                                 pBuffer[1] = pix;
585                                                 pBuffer[pitch] = pix;
586                                                 pBuffer[pitch + 1] = pix;
587
588                                                 pBuffer += 2;
589                                         }
590                                         pBuffer += pitch;
591                                 }
592                         }
593                         else if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
594                         {
595                                 const unsigned short MASK1 = 0xF81F;
596                                 const unsigned short MASK2 = 0x07E0;
597                                 const unsigned short CHROMAKEY = 0xF81F | 0x0020;
598
599                                 bool hasChromakey;
600                                 {
601                                         unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
602                                         unsigned short* pBufferEnd = pBuffer + rq_dim.width * rq_dim.height;
603
604                                         while (pBuffer < pBufferEnd)
605                                         {
606                                                 if (*pBuffer == CHROMAKEY)
607                                                 {
608                                                         break;
609                                                 }
610
611                                                 ++pBuffer;
612                                         }
613
614                                         hasChromakey = (pBuffer < pBufferEnd);
615                                 }
616
617                                 if (hasChromakey)
618                                 {
619                                         ; // pass through default scaling algorithm
620                                 }
621                                 else
622                                 {
623                                         unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
624
625                                         for (int y = 0; y < pc_dim.height; y++)
626                                         {
627                                                 for (int x = 0; x < pc_dim.width; x++)
628                                                 {
629                                                         unsigned long add1 = (unsigned long) (pBuffer[0] & MASK1) + (unsigned long) (pBuffer[1] & MASK1) + (unsigned long) (pBuffer[pitch] & MASK1) + (unsigned long) (pBuffer[pitch + 1] & MASK1);
630                                                         unsigned long add2 = (pBuffer[0] & MASK2) + (pBuffer[1] & MASK2) + (pBuffer[pitch] & MASK2) + (pBuffer[pitch + 1] & MASK2);
631
632                                                         unsigned long pix = ((add1 >> 2) & MASK1) | ((add2 >> 2) & MASK2);
633
634                                                         pBuffer[0] = pix;
635                                                         pBuffer[1] = pix;
636                                                         pBuffer[pitch] = pix;
637                                                         pBuffer[pitch + 1] = pix;
638
639                                                         pBuffer += 2;
640                                                 }
641                                                 pBuffer += pitch;
642                                         }
643                                 }
644                         }
645                 }
646
647                 result r = this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
648
649                 if (!IsFailed(r))
650                 {
651                         this->_nativeBitmap->Scale(pc_dim);
652
653                         Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
654                         Rect pc_rect(0, 0, pc_dim.width, pc_dim.height);
655
656                         this->_coordHolder->bitmapSize.required = vc_rect;
657                         this->_coordHolder->bitmapSize.phyCoord = pc_rect;
658                         this->_coordHolder->bitmapSize.virCoord = vc_rect;
659                 }
660
661                 return r;
662         }
663         else
664         {
665                 return this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
666         }
667
668 #endif
669 }
670
671 result
672 _BitmapImpl::Construct(const BufferInfo& bufferInfo)
673 {
674         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
675
676         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
677
678         SysTryReturnResult(NID_GRP, (bufferInfo.width > 0) && (bufferInfo.height > 0) && (bufferInfo.pitch > 0)
679                 , E_INVALID_ARG
680                 , "Invalid argument (BufferInfo::width = %d, BufferInfo::height = %d, BufferInfo::pitch = %d)"
681                 , bufferInfo.width, bufferInfo.height, bufferInfo.pitch);
682
683         SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel > 0
684                 , E_INVALID_ARG
685                 , "Invalid argument (BufferInfo::bitsPerPixel = %d)"
686                 , bufferInfo.bitsPerPixel);
687
688         SysTryReturnResult(NID_GRP, (bufferInfo.pixelFormat > PIXEL_FORMAT_MIN) && (bufferInfo.pixelFormat < PIXEL_FORMAT_MAX)
689                 , E_INVALID_ARG
690                 , "Invalid argument (BufferInfo::pixelFormat = %d)"
691                 , bufferInfo.pixelFormat);
692
693         SysTryReturnResult(NID_GRP, bufferInfo.pPixels != null
694                 , E_INVALID_ARG
695                 , "Invalid argument (BufferInfo::pPixels = null)");
696
697         SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel == 32 || bufferInfo.bitsPerPixel == 16
698                 , E_UNSUPPORTED_FORMAT
699                 , "Unsupported format (BufferInfo::bitsPerPixel = %d)"
700                 , bufferInfo.bitsPerPixel);
701
702         BitmapPixelFormat bitmapPixelFormat = BITMAP_PIXEL_FORMAT_MIN;
703
704         switch (bufferInfo.pixelFormat)
705         {
706         case PIXEL_FORMAT_RGB565:
707                 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_RGB565;
708                 break;
709         case PIXEL_FORMAT_ARGB8888:
710                 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
711                 break;
712         case PIXEL_FORMAT_R8G8B8A8:
713                 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_R8G8B8A8;
714                 break;
715         default:
716                 break;
717         }
718
719         SysTryReturnResult(NID_GRP, bitmapPixelFormat != BITMAP_PIXEL_FORMAT_MIN
720                 , E_UNSUPPORTED_FORMAT
721                 , "Unsupported format (BufferInfo::pixelFormat = %d)"
722                 , bufferInfo.pixelFormat);
723
724         result r = this->Construct(static_cast<const byte*>(bufferInfo.pPixels), bufferInfo.width, bufferInfo.height, bitmapPixelFormat, bufferInfo.pitch);
725
726         SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
727
728         this->_sharedItem->nativeBitmap->_SetOwnership(false);
729
730         return E_SUCCESS;
731 }
732
733 result
734 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
735 {
736         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
737
738         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
739
740         SysTryReturnResult(NID_GRP, rq_dim.width > 0 && rq_dim.height > 0, E_INVALID_ARG, "Both of width(%d) and height(%d) of a dimension MUST be greater than 0.", rq_dim.width, rq_dim.height);
741
742         SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
743
744         result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
745
746         if (r != E_SUCCESS)
747         {
748                 return r;
749         }
750
751         r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
752
753         if (!IsFailed(r))
754         {
755                 if (autoScaling)
756                 {
757                         _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
758
759                         this->_sharedItem->coordHolder->ResetFromVc(vcDim);
760
761                         // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
762
763                         Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
764                         const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
765
766                         this->_sharedItem->nativeBitmap->ScaleEx(pcDim, quality);
767                 }
768                 else
769                 {
770                         _Util::Dimension<int> pcDim = { rq_dim.width, rq_dim.height };
771
772                         this->_sharedItem->coordHolder->ResetFromPc(pcDim);
773                 }
774         }
775
776         return r;
777 }
778
779 result
780 _BitmapImpl::Construct(const byte* pBuffer, int bufSize, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
781 {
782         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
783
784         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
785
786         SysTryReturnResult(NID_GRP, pBuffer, E_INVALID_ARG, "The specified buffer pointer is invalid.");
787
788         SysTryReturnResult(NID_GRP, rq_dim.width > 0 && rq_dim.height > 0, E_INVALID_ARG, "Both of width(%d) and height(%d) of a dimension MUST be greater than 0.", rq_dim.width, rq_dim.height);
789
790         SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
791
792         SysTryReturnResult(NID_GRP, (bufSize > 0) && (bufSize >= rq_dim.width * rq_dim.height * _GetBytesPerPixel(pixelFormat)), E_INVALID_ARG, "The specified buffer size is too small (buffer size = %d, dim(%d, %d))", bufSize, rq_dim.width, rq_dim.height);
793
794         _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
795
796         this->_sharedItem->coordHolder->ResetFromVc(vcDim);
797
798         // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
799
800         result r = this->_sharedItem->nativeBitmap->Construct(pBuffer, bufSize, rq_dim, pixelFormat);
801
802         if (!IsFailed(r) && _ResUtil::NeedToConvertCoord())
803         {
804                 if (autoScaling)
805                 {
806                         Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
807                         const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
808
809                         this->_sharedItem->nativeBitmap->ScaleEx(pcDim, quality);
810                 }
811                 else
812                 {
813                         _Util::Dimension<int> pcDim = { rq_dim.width, rq_dim.height };
814
815                         this->_sharedItem->coordHolder->ResetFromPc(pcDim);
816                 }
817         }
818
819         return r;
820 }
821
822 result
823 _BitmapImpl::Construct(const byte* pExtBuffer, int width, int height, BitmapPixelFormat pixelFormat, int pitch)
824 {
825         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
826
827         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
828
829         SysTryReturnResult(NID_GRP, pExtBuffer, E_INVALID_ARG, "The specified buffer pointer is invalid.", width, height);
830
831         SysTryReturnResult(NID_GRP, width > 0 && height > 0, E_INVALID_ARG, "Both of width(%d) and height(%d) of a dimension MUST be greater than 0.", width, height);
832
833         SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
834
835         // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
836
837         int bpp = _GetBytesPerPixel(pixelFormat);
838
839         SysTryReturnResult(NID_GRP, bpp > 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
840
841         result r = this->_sharedItem->nativeBitmap->Construct(pExtBuffer, width, height, bpp * 8, pitch / bpp);
842
843         if (!IsFailed(r))
844         {
845                 _Util::Dimension<int> pcDim = { width, height };
846
847                 this->_sharedItem->coordHolder->ResetFromPc(pcDim);
848         }
849
850         return r;
851 }
852
853 result
854 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, BufferScaling bufferScaling)
855 {
856         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
857
858         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
859
860         SysTryReturnResult(NID_GRP, rq_dim.width > 0 && rq_dim.height > 0, E_INVALID_ARG, "Both of width(%d) and height(%d) of a dimension MUST be greater than 0.", rq_dim.width, rq_dim.height);
861
862         SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
863
864         result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
865
866         if (r != E_SUCCESS)
867         {
868                 return r;
869         }
870
871         switch (bufferScaling)
872         {
873         case BUFFER_SCALING_AUTO:
874                 return this->Construct(buffer, rq_dim, pixelFormat, true);
875         case BUFFER_SCALING_NONE:
876                 break;
877         default:
878                 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BufferScaling(%d) is the invalid argument.", pixelFormat);
879                 break;
880         }
881
882         _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
883
884         this->_sharedItem->coordHolder->ResetFromVc(vcDim);
885
886         // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
887
888         r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
889
890         if (!IsFailed(r) && _ResUtil::NeedToConvertCoord())
891         {
892                 this->_sharedItem->lazyScaling = 1;
893
894                 {
895                         Dimension vc_dim = rq_dim;
896                         Dimension pc_dim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
897
898                         bool isScaledBufferAvailable = false;
899                         Tizen::Base::ByteBuffer scaledBuffer;
900
901                         {
902                                 int scaledCapacity = _GetBytesPerPixel(pixelFormat) * (pc_dim.width * pc_dim.height);
903                                 SysAssert(scaledCapacity > 0);
904
905                                 // OOM ignored
906                                 isScaledBufferAvailable = (scaledBuffer.Construct(scaledCapacity) == E_SUCCESS);
907                         }
908
909                         if (isScaledBufferAvailable)
910                         {
911                                 _ScaleBuffer(scaledBuffer, pc_dim, buffer, vc_dim, pixelFormat);
912
913                                 this->_sharedItem->scaledNativeBitmap.reset(new (std::nothrow) _Bitmap);
914
915                                 if (this->_sharedItem->scaledNativeBitmap.get())
916                                 {
917                                         if (this->_sharedItem->scaledNativeBitmap->Construct(scaledBuffer, pc_dim, pixelFormat) == E_SUCCESS)
918                                         {
919                                                 // Post-processing
920
921                                                 // BufferInfo bufferInfo;
922                                                 // this->_scaledNativeBitmap->Lock(bufferInfo);
923                                                 // this->_scaledNativeBitmap->Unlock();
924                                                 ;
925                                         }
926                                         else
927                                         {
928                                                 this->_sharedItem->scaledNativeBitmap.reset(null);
929                                         }
930                                 }
931                         }
932                 }
933         }
934
935         return r;
936 }
937
938 result
939 _BitmapImpl::Construct(const Tizen::Base::String& fileName, BitmapPixelFormat pixelFormat)
940 {
941         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
942
943         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
944
945         switch (pixelFormat)
946         {
947         case BITMAP_PIXEL_FORMAT_RGB565:
948         case BITMAP_PIXEL_FORMAT_ARGB8888:
949         case BITMAP_PIXEL_FORMAT_R8G8B8A8:
950                 break;
951         default:
952                 SysTryReturnResult(NID_GRP, false, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
953                 break;
954         }
955
956         SysTryReturnResult(NID_GRP, Tizen::Io::File::IsFileExist(fileName), E_INVALID_ARG, "The specified file is not found.");
957
958         // This function doesn't verify the specified image file.
959         this->_sharedItem->associated.fileName = fileName;
960         this->_sharedItem->associated.pixelFormat = pixelFormat;
961         this->_sharedItem->associated.hasBeenDetectedByUsingName = false;
962         this->_sharedItem->associated.determinedNinePatchedAtFirst = false;
963
964         return E_SUCCESS;
965 }
966
967 result
968 _BitmapImpl::Construct(const FloatRectangle& vcRectF)
969 {
970         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
971
972         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
973
974         SysTryReturnResult(NID_GRP, vcRectF.width > 0.0f && vcRectF.height > 0.0f, E_INVALID_ARG, "Both of width(%f) and height(%f) of a rectangle MUST be greater than 0.", vcRectF.width, vcRectF.height);
975
976         SysTryReturnResult(NID_GRP, vcRectF.x >= 0.0f && vcRectF.y >= 0.0f, E_OUT_OF_RANGE, "The argument is out of range. (rect(x:%f,y:%f,w:%f,h:%f)).", vcRectF.x, vcRectF.y, vcRectF.width, vcRectF.height);
977
978         {
979                 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
980
981                 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
982
983                 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
984
985                 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
986                 Rectangle pcRect;
987
988                 pcRect.x = _FloatToIntForPos(pcRectF.x);
989                 pcRect.y = _FloatToIntForPos(pcRectF.y);
990                 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
991                 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
992
993                 return this->_sharedItem->nativeBitmap->Construct(pcRect);
994         }
995 }
996
997 result
998 _BitmapImpl::Construct(const FloatDimension& vcDimF, BitmapPixelFormat pixelFormat)
999 {
1000         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1001
1002         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
1003
1004         SysTryReturnResult(NID_GRP, vcDimF.width > 0.0f && vcDimF.height > 0.0f, E_INVALID_ARG, "Both of width(%f) and height(%f) of a dimension MUST be greater than 0.", vcDimF.width, vcDimF.height);
1005
1006         switch (pixelFormat)
1007         {
1008         case BITMAP_PIXEL_FORMAT_RGB565:
1009         case BITMAP_PIXEL_FORMAT_ARGB8888:
1010         case BITMAP_PIXEL_FORMAT_R8G8B8A8:
1011                 break;
1012         default:
1013                 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
1014                 break;
1015         }
1016
1017         {
1018                 _Util::Dimension<float> vcUtilDimF = { vcDimF.width, vcDimF.height };
1019
1020                 this->_sharedItem->coordHolder->ResetFromVc(vcUtilDimF);
1021
1022                 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
1023
1024                 return this->_sharedItem->nativeBitmap->Construct(pcDim, pixelFormat);
1025         }
1026 }
1027
1028 result
1029 _BitmapImpl::Construct(const _CanvasImpl& canvas, const FloatRectangle& vcRectF)
1030 {
1031         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1032
1033         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
1034
1035         SysTryReturnResult(NID_GRP, &canvas, E_INVALID_ARG, "A canvas is invalid.");
1036         SysTryReturnResult(NID_GRP, canvas._pNativeCanvas && canvas._pNativeCanvas->IsValid(), E_INVALID_ARG, "A canvas is invalid.");
1037
1038         FloatRectangle rtCanvasF = canvas.GetBoundsF();
1039
1040         SysTryReturnResult(NID_GRP, !rtCanvasF.IsEmpty(), E_INVALID_ARG, "A canvas is empty.");
1041
1042         SysTryReturnResult(NID_GRP, vcRectF.width > 0.0f && vcRectF.height > 0.0f, E_INVALID_ARG, "Both of width(%f) and height(%f) of a rectangle MUST be greater than 0.", vcRectF.width, vcRectF.height);
1043
1044         SysTryReturnResult(NID_GRP, _CheckValidity(vcRectF, rtCanvasF), E_OUT_OF_RANGE, "The argument is out of range. (rect(x:%f,y:%f,w:%f,h:%f)).", vcRectF.x, vcRectF.y, vcRectF.width, vcRectF.height);
1045
1046         Tizen::Graphics::_Canvas* pCanvasEx = canvas._pNativeCanvas;
1047
1048         {
1049                 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
1050
1051                 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
1052
1053                 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
1054                 Rectangle pcRect;
1055
1056                 pcRect.x = _FloatToIntForPos(pcRectF.x);
1057                 pcRect.y = _FloatToIntForPos(pcRectF.y);
1058                 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
1059                 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
1060
1061                 return this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, pcRect);
1062         }
1063 }
1064
1065 result
1066 _BitmapImpl::Construct(const _BitmapImpl& bitmap, const FloatRectangle& vcRectF)
1067 {
1068         SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1069
1070         SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
1071
1072         SysTryReturnResult(NID_GRP, BITMAPIMPL_IS_VALID(&bitmap), E_INVALID_ARG, "The source bitmap is invalid.");
1073
1074         SysTryReturnResult(NID_GRP, vcRectF.width > 0.0f && vcRectF.height > 0.0f, E_INVALID_ARG, "Both of width(%f) and height(%f) of a rectangle MUST be greater than 0.", vcRectF.width, vcRectF.height);
1075
1076         FloatRectangle rtBitmapF(0, 0, bitmap.GetWidthF(), bitmap.GetHeightF());
1077
1078         SysTryReturnResult(NID_GRP, _CheckValidity(vcRectF, rtBitmapF), E_OUT_OF_RANGE, "The argument is out of range. (rect(x:%f,y:%f,w:%f,h:%f)).", vcRectF.x, vcRectF.y, vcRectF.width, vcRectF.height);
1079
1080         _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(bitmap);
1081
1082         {
1083                 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
1084
1085                 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
1086
1087                 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
1088                 Rectangle pcRect;
1089
1090                 pcRect.x = _FloatToIntForPos(pcRectF.x);
1091                 pcRect.y = _FloatToIntForPos(pcRectF.y);
1092                 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
1093                 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
1094
1095                 result r = E_SUCCESS;
1096
1097                 if (Tizen::Graphics::_IsLazyScalingBitmap(bitmap))
1098                 {
1099                         _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(bitmap);
1100
1101                         r = this->_sharedItem->nativeBitmap->Construct(*pSrcScaledBitmapEx, pcRect);
1102                 }
1103                 else
1104                 {
1105                         r = this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, pcRect);
1106                 }
1107
1108                 return r;
1109         }
1110 }
1111
1112 result
1113 _BitmapImpl::Scale(const Dimension& vc_dim)
1114 {
1115         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1116
1117         SysTryReturnResult(NID_GRP, vc_dim.width > 0 && vc_dim.height > 0, E_OUT_OF_RANGE, "Both of width(%d) and height(%d) MUST be greater than 0.", vc_dim.width, vc_dim.height);
1118
1119         if (vc_dim.width == this->GetWidth() && vc_dim.height == this->GetHeight())
1120         {
1121                 return E_SUCCESS;
1122         }
1123         else
1124         {
1125                 return this->Scale(FloatDimension(float(vc_dim.width), float(vc_dim.height)));
1126         }
1127 }
1128
1129 result
1130 _BitmapImpl::Scale(const FloatDimension& vcDimF)
1131 {
1132         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1133
1134         SysTryReturnResult(NID_GRP, vcDimF.width > 0.0f && vcDimF.height > 0.0f, E_OUT_OF_RANGE, "Both of width(%f) and height(%f) MUST be greater than 0.", vcDimF.width, vcDimF.height);
1135
1136         if (vcDimF.width == this->GetWidthF() && vcDimF.height == this->GetHeightF())
1137         {
1138                 return E_SUCCESS;
1139         }
1140
1141         _UpdateBitmapTimeStamp(*this);
1142
1143         result r = E_SUCCESS;
1144
1145         _Util::AccumList<_Util::Pair<float, float> > scalingValue;
1146
1147         _GetScaleInfo(this->GetScalingQuality(), this->GetWidthF(), this->GetHeightF(), vcDimF.width, vcDimF.height, scalingValue);
1148
1149         for (_Util::AccumList<_Util::Pair<float, float> >::Iterator iter = scalingValue.End(); iter != scalingValue.Begin(); --iter)
1150         {
1151                 this->__Scale((iter-1)->first, (iter-1)->second);
1152         }
1153
1154         return r;
1155 }
1156
1157 result
1158 _BitmapImpl::Merge(const Point& vc_dest, const _BitmapImpl& src, const Rectangle& vc_srcRect)
1159 {
1160         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1161
1162         SysTryReturnResult(NID_GRP, &src && src._sharedItem.get(), E_INVALID_ARG, "The source bitmap is invalid.");
1163
1164         SysTryReturnResult(NID_GRP, src._sharedItem->nativeBitmap->IsValid(), E_INVALID_ARG, "The source bitmap is invalid.");
1165
1166         SysTryReturnResult(NID_GRP, &vc_srcRect, E_INVALID_ARG, "The source rectangle is invalid.");
1167         SysTryReturnResult(NID_GRP, &vc_dest, E_INVALID_ARG, "The destination position is invalid.");
1168         SysTryReturnResult(NID_GRP, vc_dest.x >= 0 && vc_dest.y >= 0, E_OUT_OF_RANGE, "The argument is out of range. (dest(x:%d,y:%d)).", vc_dest.x, vc_dest.y);
1169
1170         SysTryReturnResult(NID_GRP, (vc_srcRect.width >= 0) && (vc_srcRect.height >= 0), E_INVALID_ARG, "The given rectangle(width:%d,height:%d) is invalid.", vc_srcRect.width, vc_srcRect.height);
1171
1172         if ((vc_srcRect.width == 0) || (vc_srcRect.height == 0))
1173         {
1174                 return E_SUCCESS;
1175         }
1176         else
1177         {
1178                 Rectangle rtBitmap(0, 0, src.GetWidth(), src.GetHeight());
1179                 SysTryReturnResult(NID_GRP, _CheckValidity(vc_srcRect, rtBitmap), E_OUT_OF_RANGE, "The argument is out of range. (srcRect(x:%d,y:%d,w:%d,h:%d)).", vc_srcRect.x, vc_srcRect.y, vc_srcRect.width, vc_srcRect.height);
1180
1181                 return this->Merge(FloatPoint(float(vc_dest.x), float(vc_dest.y)), src, FloatRectangle(float(vc_srcRect.x), float(vc_srcRect.y), float(vc_srcRect.width), float(vc_srcRect.height)));
1182         }
1183 }
1184
1185 result
1186 _BitmapImpl::Merge(const FloatPoint& destVcPosF, const _BitmapImpl& srcBitmap, const FloatRectangle& srcVcRectF)
1187 {
1188         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1189
1190         SysTryReturnResult(NID_GRP, &srcBitmap && srcBitmap._sharedItem.get(), E_INVALID_ARG, "The source bitmap is invalid.");
1191
1192         SysTryReturnResult(NID_GRP, srcBitmap._sharedItem->nativeBitmap->IsValid(), E_INVALID_ARG, "The source bitmap is invalid.");
1193
1194         SysTryReturnResult(NID_GRP, &srcVcRectF, E_INVALID_ARG, "The source rectangle is invalid.");
1195         SysTryReturnResult(NID_GRP, &destVcPosF, E_INVALID_ARG, "The destination position is invalid.");
1196         SysTryReturnResult(NID_GRP, destVcPosF.x >= 0.0f && destVcPosF.y >= 0.0f, E_OUT_OF_RANGE, "The argument is out of range. (destPoint(x:%f,y:%f)).", destVcPosF.x, destVcPosF.y);
1197
1198         SysTryReturnResult(NID_GRP, srcVcRectF.width >= 0.0f && srcVcRectF.height >= 0.0f, E_INVALID_ARG, "The given rectangle(width:%f,height:%f) is invalid.", srcVcRectF.width, srcVcRectF.height);
1199
1200         if ((srcVcRectF.width == 0.0f) || (srcVcRectF.height == 0.0f))
1201         {
1202                 return E_SUCCESS;
1203         }
1204
1205         FloatRectangle rtBitmapF(0, 0, srcBitmap.GetWidthF(), srcBitmap.GetHeightF());
1206         SysTryReturnResult(NID_GRP, _CheckValidity(srcVcRectF, rtBitmapF), E_OUT_OF_RANGE, "The argument is out of range. (srcRect(x:%f,y:%f,w:%f,h:%f)).", srcVcRectF.x, srcVcRectF.y, srcVcRectF.width, srcVcRectF.height);
1207
1208         _UpdateBitmapTimeStamp(*this);
1209
1210         _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(srcBitmap);
1211         _Bitmap* pDstBitmapEx = this->_sharedItem->nativeBitmap.get();
1212
1213         Point destVcPos(_FloatToIntForPos(destVcPosF.x), _FloatToIntForPos(destVcPosF.y));
1214         Rectangle srcVcRect;
1215
1216         srcVcRect.x = _FloatToIntForPos(srcVcRectF.x);
1217         srcVcRect.y = _FloatToIntForPos(srcVcRectF.y);
1218         srcVcRect.width = _FloatToIntForPos(srcVcRectF.GetBottomRight().x - srcVcRectF.GetTopLeft().x);
1219         srcVcRect.height= _FloatToIntForPos(srcVcRectF.GetBottomRight().y - srcVcRectF.GetTopLeft().y);
1220
1221         if (_ResUtil::NeedToConvertCoord())
1222         {
1223                 FloatPoint destPcPosF = _ResUtil::ConvertToPhyCoord(destVcPosF);
1224                 FloatRectangle srcPcRectF = _ResUtil::ConvertToPhyCoord(srcVcRectF);
1225
1226                 Point destPcPos(_FloatToIntForPos(destPcPosF.x), _FloatToIntForPos(destPcPosF.y));
1227                 Rectangle srcPcRect;
1228
1229                 srcPcRect.x = _FloatToIntForPos(srcPcRectF.x);
1230                 srcPcRect.y = _FloatToIntForPos(srcPcRectF.y);
1231                 srcPcRect.width = _FloatToIntForPos(srcPcRectF.GetBottomRight().x - srcPcRectF.GetTopLeft().x);
1232                 srcPcRect.height= _FloatToIntForPos(srcPcRectF.GetBottomRight().y - srcPcRectF.GetTopLeft().y);
1233
1234                 /*
1235                     case 0: scaled bitmap -> scaled bitmap
1236                         merge level 0
1237                     case 1: scaled bitmap -> lazy scaled bitmap
1238                         merge level 0 from the scaled source bitmap
1239                         merge level 0(src) and level 1(dst)
1240                     case 2: lazy scaled bitmap -> scaled bitmap
1241                         merge level 1(src) and level 0(dst)
1242                     case 3: lazy scaled bitmap ->  lazy scaled bitmap
1243                         merge level 0 (using virtual coordinate)
1244                         merge level 1 (using physical coordinate)
1245                 */
1246                 int caseNo = (Tizen::Graphics::_IsLazyScalingBitmap(srcBitmap)) ? 2 : 0;
1247                 caseNo += (Tizen::Graphics::_IsLazyScalingBitmap(*this)) ? 1 : 0;
1248
1249                 switch (caseNo)
1250                 {
1251                 case 0: // source: pre-scale, destination: pre-scale --> merge by using the physical coordinate
1252                 {
1253                         return pDstBitmapEx->Merge(destPcPos, *pSrcBitmapEx, srcPcRect);
1254                 }
1255                 case 1: // source: pre-scale --> level0 bitmap: merge after enlarging, level1 bitmap: merge from source directly
1256                 {
1257                         result r = E_SUCCESS;
1258
1259                         // step 1
1260                         {
1261                                 _Bitmap srcResizedBitmap;
1262                                 {
1263                                         Dimension srcVcDim;
1264
1265                                         srcVcDim.width = static_cast<int>(srcBitmap._sharedItem->coordHolder->size.vcFloatActual.w);
1266                                         srcVcDim.height = static_cast<int>(srcBitmap._sharedItem->coordHolder->size.vcFloatActual.h);
1267
1268                                         r = srcResizedBitmap.Construct(srcVcDim, pSrcBitmapEx->GetPixelColorFormat());
1269
1270                                         SysTryReturnResult(NID_GRP, !IsFailed(r), E_OUT_OF_MEMORY, "Fails to allocate memory.");
1271                                 }
1272
1273                                 _UpdateScaledBitmapEx(pSrcBitmapEx, &srcResizedBitmap);
1274
1275                                 r = pDstBitmapEx->Merge(destVcPos, srcResizedBitmap, srcVcRect);
1276                         }
1277
1278                         // step 2
1279                         if (!IsFailed(r) && this->_sharedItem->scaledNativeBitmap.get())
1280                         {
1281                                 return this->_sharedItem->scaledNativeBitmap->Merge(destPcPos, *pSrcBitmapEx, srcPcRect);
1282                         }
1283
1284                         return r;
1285                 }
1286                 case 2: // destination: pre-scale --> merge from the level1 bitmap of source
1287                 {
1288                         _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(srcBitmap);
1289
1290                         SysTryReturnResult(NID_GRP, pSrcScaledBitmapEx != null, E_INVALID_ARG, "The source bitmap is invalid.");
1291
1292                         return pDstBitmapEx->Merge(destPcPos, *pSrcScaledBitmapEx, srcPcRect);
1293                 }
1294                 case 3: // source: lazy-scale, destination: lazy-scale --> merge between level0, merge between level1
1295                 {
1296                         result r = pDstBitmapEx->Merge(destVcPos, *pSrcBitmapEx, srcVcRect);
1297
1298                         _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(srcBitmap);
1299
1300                         if (this->_sharedItem->scaledNativeBitmap.get() && pSrcScaledBitmapEx)
1301                         {
1302                                 this->_sharedItem->scaledNativeBitmap->Merge(destPcPos, *pSrcScaledBitmapEx, srcPcRect);
1303                         }
1304
1305                         return r;
1306                 }
1307                 default:
1308                         SysAssert(0);
1309                         return E_INVALID_ARG;
1310                 }
1311         }
1312         else
1313         {
1314                 return pDstBitmapEx->Merge(destVcPos, *pSrcBitmapEx, srcVcRect);
1315         }
1316
1317         // for removing compiler warnings
1318         return E_OPERATION_FAILED;
1319 }
1320
1321 int
1322 _BitmapImpl::GetHeight() const
1323 {
1324         if (!(INSTANCE_IS_VALID))
1325         {
1326                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1327                 return -1;
1328         }
1329
1330         return this->_sharedItem->coordHolder->size.vcInt.h;
1331 }
1332
1333 float
1334 _BitmapImpl::GetHeightF(void) const
1335 {
1336         if (!(INSTANCE_IS_VALID))
1337         {
1338                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1339                 return -1.0f;
1340         }
1341
1342         return this->_sharedItem->coordHolder->size.vcFloat.h;
1343 }
1344
1345 float
1346 _BitmapImpl::GetActualHeight(void) const
1347 {
1348         if (!(INSTANCE_IS_VALID))
1349         {
1350                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1351                 return -1.0f;
1352         }
1353
1354         return this->_sharedItem->coordHolder->size.vcFloatActual.h;
1355 }
1356
1357 int
1358 _BitmapImpl::GetWidth() const
1359 {
1360         if (!(INSTANCE_IS_VALID))
1361         {
1362                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1363                 return -1;
1364         }
1365
1366         return this->_sharedItem->coordHolder->size.vcInt.w;
1367 }
1368
1369 float
1370 _BitmapImpl::GetWidthF(void) const
1371 {
1372         if (!(INSTANCE_IS_VALID))
1373         {
1374                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1375                 return -1.0f;
1376         }
1377
1378         return this->_sharedItem->coordHolder->size.vcFloat.w;
1379 }
1380
1381 float
1382 _BitmapImpl::GetActualWidth(void) const
1383 {
1384         if (!(INSTANCE_IS_VALID))
1385         {
1386                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1387                 return -1.0f;
1388         }
1389
1390         return this->_sharedItem->coordHolder->size.vcFloatActual.w;
1391 }
1392
1393 int
1394 _BitmapImpl::GetBitsPerPixel() const
1395 {
1396         if (!(INSTANCE_IS_VALID))
1397         {
1398                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1399                 return -1;
1400         }
1401
1402         return this->_sharedItem->nativeBitmap->GetBitsPerPixel();
1403 }
1404
1405 BitmapPixelFormat
1406 _BitmapImpl::GetPixelColorFormat() const
1407 {
1408         if (!(INSTANCE_IS_VALID))
1409         {
1410                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1411                 return BITMAP_PIXEL_FORMAT_MAX;
1412         }
1413
1414         return this->_sharedItem->nativeBitmap->GetPixelColorFormat();
1415 }
1416
1417 result
1418 _BitmapImpl::SetMaskingColor(const Color* pColor)
1419 {
1420         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1421
1422         _UpdateBitmapTimeStamp(*this);
1423
1424         return this->_sharedItem->nativeBitmap->SetMaskingColor(pColor);
1425 }
1426
1427 result
1428 _BitmapImpl::GetMaskingColor(Color& color) const
1429 {
1430         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1431
1432         return this->_sharedItem->nativeBitmap->GetMaskingColor(color);
1433 }
1434
1435 void
1436 _BitmapImpl::SetAlphaConstant(int opacity)
1437 {
1438         if (INSTANCE_IS_VALID)
1439         {
1440                 _UpdateBitmapTimeStamp(*this);
1441
1442                 this->_sharedItem->nativeBitmap->SetAlphaConstant(opacity);
1443         }
1444 }
1445
1446 int
1447 _BitmapImpl::GetAlphaConstant(void) const
1448 {
1449         return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetAlphaConstant() : -1;
1450 }
1451
1452 result
1453 _BitmapImpl::SetScalingQuality(BitmapScalingQuality quality)
1454 {
1455         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1456
1457         switch (quality)
1458         {
1459         case BITMAP_SCALING_QUALITY_LOW:
1460         case BITMAP_SCALING_QUALITY_MID:
1461         case BITMAP_SCALING_QUALITY_HIGH:
1462                 break;
1463         default:
1464                 return E_INVALID_ARG;
1465         }
1466
1467         _UpdateBitmapTimeStamp(*this);
1468
1469         this->_sharedItem->nativeBitmap->SetScalingQuality(quality);
1470
1471         return E_SUCCESS;
1472 }
1473
1474 BitmapScalingQuality
1475 _BitmapImpl::GetScalingQuality(void) const
1476 {
1477         return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetScalingQuality() : BITMAP_SCALING_QUALITY_LOW;
1478 }
1479
1480 bool
1481 _BitmapImpl::IsNinePatchedBitmap(void) const
1482 {
1483 #if 1
1484         if (!(INSTANCE_IS_VALID))
1485         {
1486                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1487                 return false;
1488         }
1489
1490         _Bitmap* pRefBitmap = (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get()) ? this->_sharedItem->scaledNativeBitmap.get() : this->_sharedItem->nativeBitmap.get();
1491
1492         return pRefBitmap->IsNinePatchedBitmap();
1493 #else
1494         if (!(IS_INSTANCE_VALID))
1495         {
1496                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1497                 return false;
1498         }
1499
1500         const Tizen::Base::String& associatedFileName = this->_sharedItem->associated.fileName;
1501
1502         if (associatedFileName.IsEmpty())
1503         {
1504                 _Bitmap* pRefBitmap = (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get()) ? this->_sharedItem->scaledNativeBitmap.get() : this->_sharedItem->nativeBitmap.get();
1505
1506                 return pRefBitmap->IsNinePatchedBitmap();
1507         }
1508         else
1509         {
1510                 return HasNinePatchedBitmapTag(associatedFileName);
1511         }
1512 #endif
1513 }
1514
1515 void
1516 _BitmapImpl::SetAsImmutable(void)
1517 {
1518         if (INSTANCE_IS_VALID)
1519         {
1520                 if (this->_sharedItem->isMutable)
1521                 {
1522                         BufferInfo bi;
1523
1524                         if (this->Lock(bi) == E_SUCCESS)
1525                         {
1526                                 _Util::Pixmap dstImage(bi.width, bi.height, bi.bitsPerPixel, (void*)bi.pPixels, bi.pitch);
1527                                 dstImage.ConvertPremultiplied();
1528
1529                                 this->Unlock();
1530                         }
1531
1532                         this->_sharedItem->isMutable = false;
1533                         this->_sharedItem->nativeBitmap->__isPremultiplied = true;
1534
1535                         //?? this->_sharedItem->scaledNativeBitmap
1536                 }
1537         }
1538 }
1539
1540 bool
1541 _BitmapImpl::IsMutable(void) const
1542 {
1543         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, false, "This instance is not constructed yet.");
1544
1545         return this->_sharedItem->isMutable;
1546 }
1547
1548 result
1549 _BitmapImpl::Lock(BufferInfo& info, long timeout)
1550 {
1551         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1552
1553         _UpdateBitmapTimeStamp(*this);
1554
1555         return this->_sharedItem->nativeBitmap->Lock(info, timeout);
1556 }
1557
1558 result
1559 _BitmapImpl::Unlock()
1560 {
1561         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1562
1563         result r = this->_sharedItem->nativeBitmap->Unlock();
1564
1565         _UpdateBitmapTimeStamp(*this);
1566
1567         if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1568         {
1569                 if (this->_sharedItem->scaledNativeBitmap.get())
1570                 {
1571                         _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1572                         this->_sharedItem->scaledNativeBitmap->UpdateOpaqueInfo();
1573                 }
1574         }
1575
1576         return r;
1577 }
1578
1579 result
1580 _BitmapImpl::LockFast(BufferInfo& info, long timeout)
1581 {
1582         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1583
1584         _UpdateBitmapTimeStamp(*this);
1585
1586         return this->_sharedItem->nativeBitmap->LockFast(info, timeout);
1587 }
1588
1589 result
1590 _BitmapImpl::UnlockFast()
1591 {
1592         SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1593
1594         result r = this->_sharedItem->nativeBitmap->UnlockFast();
1595
1596         _UpdateBitmapTimeStamp(*this);
1597
1598         if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1599         {
1600                 if (this->_sharedItem->scaledNativeBitmap.get())
1601                 {
1602                         _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1603                 }
1604         }
1605
1606         return r;
1607 }
1608
1609 bool
1610 _BitmapImpl::CheckNinePatchedBitmapStrictly(const Bitmap& bitmap)
1611 {
1612         const _BitmapImpl* pThis = _BitmapImpl::GetInstance(bitmap);
1613
1614         if (!(IS_BITMAPIMPL_VALID(pThis)))
1615         {
1616                 SysLog(NID_GRP, "[E_OPERATION_FAILED] The given bitmap is not constructed yet.");
1617                 return false;
1618         }
1619
1620         if (pThis->_sharedItem->associated.hasBeenDetectedByUsingName)
1621         {
1622                 return pThis->_sharedItem->associated.determinedNinePatchedAtFirst;
1623         }
1624
1625         const Tizen::Base::String& associatedFileName = pThis->_sharedItem->associated.fileName;
1626
1627         if (associatedFileName.IsEmpty())
1628         {
1629                 _Bitmap* pRefBitmap = (pThis->_sharedItem->lazyScaling && pThis->_sharedItem->scaledNativeBitmap.get()) ? pThis->_sharedItem->scaledNativeBitmap.get() : pThis->_sharedItem->nativeBitmap.get();
1630
1631                 return pRefBitmap->IsNinePatchedBitmap(true);
1632         }
1633         else
1634         {
1635                 bool ret = HasNinePatchedBitmapTag(associatedFileName);
1636
1637                 pThis->_sharedItem->associated.hasBeenDetectedByUsingName = true;
1638                 pThis->_sharedItem->associated.determinedNinePatchedAtFirst = ret;
1639
1640                 return ret;
1641         }
1642 }
1643
1644 bool
1645 _BitmapImpl::_SetCallback(void (* DestroyCallback)(void*), void* pDestroyCallbackParam,
1646                               void (* LockCallback)(void*), void* pLockCallbackParam,
1647                               void (* UnlockCallback)(void*), void* pUnlockCallbackParam)
1648 {
1649         if (!(INSTANCE_IS_VALID))
1650         {
1651                 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1652                 return false;
1653         }
1654
1655         _UpdateBitmapTimeStamp(*this);
1656
1657         this->_sharedItem->pDestroyCallbackFunc = DestroyCallback;
1658         this->_sharedItem->pDestroyCallbackParam = pDestroyCallbackParam;
1659
1660         this->_sharedItem->pLockCallbackFunc = LockCallback;
1661         this->_sharedItem->pLockCallbackParam = pLockCallbackParam;
1662
1663         this->_sharedItem->pUnlockCallbackFunc = UnlockCallback;
1664         this->_sharedItem->pUnlockCallbackParam = pUnlockCallbackParam;
1665
1666         if (this->_sharedItem->nativeBitmap.get())
1667         {
1668                 this->_sharedItem->nativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam);
1669         }
1670
1671         if (this->_sharedItem->scaledNativeBitmap.get())
1672         {
1673                 this->_sharedItem->scaledNativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam);
1674         }
1675
1676         return true;
1677 }
1678
1679 Bitmap*
1680 _BitmapImpl::GetExpandedBitmapN(const Bitmap& ninePatchedBitmap, int width, int height)
1681 {
1682         SysTryReturn(NID_GRP, width > 0 && height > 0, null, E_INVALID_ARG, "[E_INVALID_ARG] The given parameter is invalid (width = %d, height = %d)", width, height);
1683
1684         SysTryReturn(NID_GRP, &ninePatchedBitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1685
1686         const _BitmapImpl* pSrcBitmapImpl = _BitmapImpl::GetInstance(ninePatchedBitmap);
1687
1688         SysTryReturn(NID_GRP, BITMAPIMPL_IS_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1689
1690         SysTryReturn(NID_GRP, pSrcBitmapImpl->IsNinePatchedBitmap(), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is not a nine-patched bitmap");
1691
1692         BitmapPixelFormat pixelFormat = pSrcBitmapImpl->GetPixelColorFormat();
1693
1694         switch (pixelFormat)
1695         {
1696         case BITMAP_PIXEL_FORMAT_RGB565:
1697         case BITMAP_PIXEL_FORMAT_ARGB8888:
1698                 break;
1699         default:
1700                 SysTryReturn(NID_GRP, false, null, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] Pixel format of the given bitmap is invalid (%d)", pixelFormat);
1701                 break;
1702         }
1703
1704         return _BitmapImpl::GetExpandedBitmapFN(ninePatchedBitmap, float(width), float (height));
1705 }
1706
1707 Bitmap*
1708 _BitmapImpl::GetExpandedBitmapFN(const Bitmap& ninePatchedBitmap, float width, float height)
1709 {
1710         SysTryReturn(NID_GRP, width > 0.0f && height > 0.0f, null, E_INVALID_ARG, "[E_INVALID_ARG] The given parameter is invalid (width = %f, height = %f)", width, height);
1711
1712         SysTryReturn(NID_GRP, &ninePatchedBitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1713
1714         const _BitmapImpl* pSrcBitmapImpl = _BitmapImpl::GetInstance(ninePatchedBitmap);
1715
1716         SysTryReturn(NID_GRP, BITMAPIMPL_IS_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1717
1718         SysTryReturn(NID_GRP, pSrcBitmapImpl->IsNinePatchedBitmap(), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is not a nine-patched bitmap");
1719
1720         BitmapPixelFormat pixelFormat = pSrcBitmapImpl->GetPixelColorFormat();
1721
1722         switch (pixelFormat)
1723         {
1724         case BITMAP_PIXEL_FORMAT_RGB565:
1725         case BITMAP_PIXEL_FORMAT_ARGB8888:
1726                 break;
1727         default:
1728                 SysTryReturn(NID_GRP, false, null, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] Pixel format of the given bitmap is invalid (%d)", pixelFormat);
1729                 break;
1730         }
1731
1732         std::auto_ptr<Bitmap> expandedBitmap(new (std::nothrow) Bitmap);
1733
1734         SysTryReturn(NID_GRP, expandedBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1735
1736         result r = expandedBitmap->Construct(FloatDimension(width, height), pixelFormat);
1737
1738         SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1739
1740         _BitmapImpl* pDstBitmapImpl = _BitmapImpl::GetInstance(*expandedBitmap.get());
1741
1742         SysAssert(pDstBitmapImpl != null);
1743
1744         {
1745                 _Util::LockManager srcBitmap(*pSrcBitmapImpl);
1746                 _Util::LockManager dstBitmap(*pDstBitmapImpl);
1747
1748                 SysTryReturn(NID_GRP, srcBitmap.IsValid(), null, srcBitmap.GetResult(), "[%s] Buffer locking of the source bitmap failed", srcBitmap.GetResult());
1749                 SysTryReturn(NID_GRP, dstBitmap.IsValid(), null, dstBitmap.GetResult(), "[%s] Buffer locking of the target bitmap failed", dstBitmap.GetResult());
1750
1751                 if (dstBitmap.GetBufferInfo().width < srcBitmap.GetBufferInfo().width - 2 ||
1752                         dstBitmap.GetBufferInfo().height < srcBitmap.GetBufferInfo().height - 2)
1753                 {
1754                         // down-scales from the source bitmap only
1755                         const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1756                         const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1757
1758                         memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1759
1760                         _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1761
1762                         Rectangle sourRect(1, 1, srcBufferInfo.width - 2, srcBufferInfo.height - 2);
1763                         Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
1764
1765                         unsigned char* pSrcPixels = (unsigned char*) srcBufferInfo.pPixels + sourRect.y * srcBufferInfo.pitch + sourRect.x * (srcBufferInfo.bitsPerPixel / 8);
1766                         _Util::Pixmap srcImage(sourRect.width, sourRect.height, srcBufferInfo.bitsPerPixel, (void*) pSrcPixels, srcBufferInfo.pitch);
1767
1768                         Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1769                 }
1770                 else
1771                 {
1772                         const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1773                         const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1774
1775                         memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1776
1777                         _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1778
1779                         _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
1780
1781                         Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
1782
1783                         // assert(pSrcBitmapImpl->_nativeBitmap);
1784                         r = _Util::GetPatchList(boundsList, destRect, *pSrcBitmapImpl->_sharedItem->nativeBitmap.get());
1785
1786                         SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] _Util::GetPatchList() failed (error = %#x)", r);
1787
1788                         _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
1789
1790                         while (iter != boundsList.End())
1791                         {
1792                                 Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
1793                                 Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
1794
1795                                 {
1796                                         unsigned char* pSrcPixels = (unsigned char*) srcBufferInfo.pPixels + sourRect.y * srcBufferInfo.pitch + sourRect.x * (srcBufferInfo.bitsPerPixel / 8);
1797                                         _Util::Pixmap srcImage(sourRect.width, sourRect.height, srcBufferInfo.bitsPerPixel, (void*) pSrcPixels, srcBufferInfo.pitch);
1798
1799                                         Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1800                                 }
1801
1802                                 ++iter;
1803                         }
1804                 }
1805         }
1806
1807         return expandedBitmap.release();
1808 }
1809
1810 Bitmap*
1811 _BitmapImpl::GetColorReplacedBitmapN(const Bitmap& bitmap, const Color& replacedColor, const Color& newColor)
1812 {
1813         SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1814
1815         std::auto_ptr<Bitmap> pRetBitmap;
1816
1817         {
1818                 Bitmap* pSrcBitmap = const_cast<Bitmap*>(&bitmap);
1819
1820                 BufferInfo biSrc;
1821                 pSrcBitmap->Lock(biSrc);
1822                 {
1823                         pRetBitmap.reset(_BitmapUtil::CreateBitmapN(Dimension(biSrc.width, biSrc.height), biSrc.bitsPerPixel));
1824
1825                         if (pRetBitmap.get())
1826                         {
1827                                 BufferInfo biDst;
1828                                 pRetBitmap->Lock(biDst);
1829
1830                                 if ((biSrc.pitch == biDst.pitch) && (biSrc.height == biDst.height))
1831                                 {
1832                                         memcpy(biDst.pPixels, biSrc.pPixels, biDst.pitch * biDst.height);
1833                                 }
1834
1835                                 pRetBitmap->Unlock();
1836                         }
1837                 }
1838                 pSrcBitmap->Unlock();
1839
1840                 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] New bitmap construction failed");
1841         }
1842
1843         BufferInfo bufferInfo;
1844
1845         result r = pRetBitmap->Lock(bufferInfo);
1846
1847         SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap cannot retrieve the own buffer address");
1848
1849         if (bufferInfo.bitsPerPixel == 32)
1850         {
1851                 typedef unsigned long Pixel;
1852
1853                 Pixel keyColor = replacedColor.GetRGB32() & 0x00FFFFFF;
1854                 Pixel chgColor = newColor.GetRGB32() & 0x00FFFFFF;
1855                 Pixel* pBuffer = reinterpret_cast<Pixel*>(bufferInfo.pPixels);
1856                 int padding = bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel - bufferInfo.width;
1857
1858                 Pixel keyAlpha = (newColor.GetRGB32() & 0xFF000000) >> 24;
1859                 keyAlpha += (keyAlpha >> 7);
1860
1861                 if (keyAlpha < 256)
1862                 {
1863                         for (int y = 0; y < bufferInfo.height; y++)
1864                         {
1865                                 for (int x = 0; x < bufferInfo.width; x++)
1866                                 {
1867                                         // if buffer.rgb = replacedColor.rgb then begin
1868                                         //    buffer.a <- buffer.a * newColor.a;
1869                                         //    buffer.r <- newColor.r;
1870                                         //    buffer.g <- newColor.g;
1871                                         //    buffer.b <- newColor.b;
1872                                         // end if
1873
1874                                         if ((*pBuffer & 0x00FFFFFF) == keyColor)
1875                                         {
1876                                                 Pixel alpha = (*pBuffer >> 8) & 0x00FF0000;
1877                                                 alpha = (alpha * keyAlpha) & 0xFF000000;
1878
1879                                                 *pBuffer = alpha | chgColor;
1880                                         }
1881
1882                                         ++pBuffer;
1883                                 }
1884
1885                                 pBuffer += padding;
1886                         }
1887                 }
1888                 else
1889                 {
1890                         for (int y = 0; y < bufferInfo.height; y++)
1891                         {
1892                                 for (int x = 0; x < bufferInfo.width; x++)
1893                                 {
1894                                         // if buffer.rgb = replacedColor.rgb then begin
1895                                         //    buffer.a <- buffer.a;
1896                                         //    buffer.r <- newColor.r;
1897                                         //    buffer.g <- newColor.g;
1898                                         //    buffer.b <- newColor.b;
1899                                         // end if
1900
1901                                         if ((*pBuffer & 0x00FFFFFF) == keyColor)
1902                                         {
1903                                                 *pBuffer = (*pBuffer & 0xFF000000) | chgColor;
1904                                         }
1905
1906                                         ++pBuffer;
1907                                 }
1908
1909                                 pBuffer += padding;
1910                         }
1911                 }
1912         }
1913         else if (bufferInfo.bitsPerPixel == 16)
1914         {
1915                 typedef unsigned short Pixel;
1916
1917                 Pixel keyColor = 0;
1918                 Pixel chgColor = 0;
1919                 Pixel* pBuffer = reinterpret_cast<Pixel*>(bufferInfo.pPixels);
1920                 int padding = bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel - bufferInfo.width;
1921
1922                 {
1923                         unsigned long color32 = replacedColor.GetRGB32();
1924                         _Effect::Func::ConvertColorFormatFast(&keyColor, &color32);
1925                 }
1926
1927                 {
1928                         unsigned long color32 = newColor.GetRGB32() & 0x00FFFFFF;
1929                         _Effect::Func::ConvertColorFormatFast(&chgColor, &color32);
1930                 }
1931
1932                 for (int y = 0; y < bufferInfo.height; y++)
1933                 {
1934                         for (int x = 0; x < bufferInfo.width; x++)
1935                         {
1936                                 if (*pBuffer == keyColor)
1937                                 {
1938                                         *pBuffer = chgColor;
1939                                 }
1940
1941                                 ++pBuffer;
1942                         }
1943
1944                         pBuffer += padding;
1945                 }
1946         }
1947         else
1948         {
1949                 return null;
1950         }
1951
1952         pRetBitmap->Unlock();
1953
1954         return pRetBitmap.release();
1955 }
1956
1957 Bitmap*
1958 _BitmapImpl::CloneN(const Bitmap& bitmap)
1959 {
1960         const _BitmapImpl* pSrcBitmapImpl = null;
1961         _BitmapImpl* pDstBitmapImpl = null;
1962
1963         // source bitmap verification
1964         {
1965                 SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1966
1967                 pSrcBitmapImpl = _BitmapImpl::GetInstance(bitmap);
1968
1969                 SysTryReturn(NID_GRP, IS_BITMAPIMPL_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1970         }
1971
1972         // destination bitmap allocation
1973         std::auto_ptr<Bitmap> pRetBitmap(new (std::nothrow) Bitmap);
1974
1975         {
1976                 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1977
1978                 pDstBitmapImpl = _BitmapImpl::GetInstance(*pRetBitmap.get());
1979
1980                 SysTryReturn(NID_GRP, pDstBitmapImpl && pDstBitmapImpl->_sharedItem.get() && !pDstBitmapImpl->_sharedItem->nativeBitmap->IsValid(), null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap is invalid");
1981         }
1982
1983         pDstBitmapImpl->_sharedItem = pSrcBitmapImpl->_sharedItem;
1984
1985         return pRetBitmap.release();
1986 }
1987
1988 _BitmapImpl*
1989 _BitmapImpl::GetNonScaledBitmapImplN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
1990 {
1991         return _NonScale::CreateBitmapN(buffer, dim, pixelFormat);
1992 }
1993
1994 Bitmap*
1995 _BitmapImpl::GetNonScaledBitmapN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
1996 {
1997         _BitmapImpl* pBitmapImpl = _BitmapImpl::GetNonScaledBitmapImplN(buffer, dim, pixelFormat);
1998
1999         if (pBitmapImpl == null)
2000         {
2001                 return null;
2002         }
2003
2004         return Tizen::Graphics::_BitmapUtil::CreateBitmapN(pBitmapImpl);
2005 }
2006
2007 Bitmap*
2008 _BitmapImpl::GetNonScaledBitmapN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat, const FloatDimension& logicalSize)
2009 {
2010         Bitmap* pBitmap = GetNonScaledBitmapN(buffer, dim, pixelFormat);
2011
2012         if (pBitmap)
2013         {
2014                 _BitmapImpl* pBitmapImpl = _BitmapImpl::GetInstance(*pBitmap);
2015
2016                 if (pBitmapImpl)
2017                 {
2018                         pBitmapImpl->_sharedItem->coordHolder->size.vcFloat.w = logicalSize.width;
2019                         pBitmapImpl->_sharedItem->coordHolder->size.vcFloat.h = logicalSize.height;
2020                 }
2021                 else
2022                 {
2023                         delete pBitmap;
2024                         pBitmap = null;
2025                 }
2026         }
2027
2028         return pBitmap;
2029 }
2030
2031 bool
2032 _BitmapImpl::HasNinePatchedBitmapTag(Tizen::Base::String fileName)
2033 {
2034         const wchar_t* NINE_PATCHED_TAG = L".#.png"; // it must consist of lower-case characters
2035         const int NINE_PATCHED_TAG_LENGTH = 6;
2036
2037         struct Temp
2038         {
2039                 static wchar_t ToLower(wchar_t ch)
2040                 {
2041                         return (ch >= L'A' && ch <= L'Z') ? ch + 'a' - 'A' : ch;
2042                 }
2043         };
2044
2045         _Util::String tempStr(fileName.GetPointer(), fileName.GetLength());
2046
2047         while (tempStr.length > 0 && tempStr.pStart[tempStr.length - 1] == L' ')
2048         {
2049                 --tempStr.length;
2050         }
2051
2052         _Util::String testStr(tempStr.pStart, tempStr.length, tempStr.length - NINE_PATCHED_TAG_LENGTH, NINE_PATCHED_TAG_LENGTH);
2053
2054         if (testStr.length == NINE_PATCHED_TAG_LENGTH)
2055         {
2056                 for (int i = 0; i < NINE_PATCHED_TAG_LENGTH; i++)
2057                 {
2058                         if (Temp::ToLower(testStr.pStart[i]) == NINE_PATCHED_TAG[i])
2059                         {
2060                                 continue;
2061                         }
2062
2063                         return false;
2064                 }
2065
2066                 return true;
2067         }
2068
2069         return false;
2070 }
2071
2072 void
2073 _BitmapImpl::SetAsPremultiplied(void)
2074 {
2075         if (IS_INSTANCE_VALID)
2076         {
2077                 this->_sharedItem->isMutable = false;
2078                 this->_sharedItem->nativeBitmap->__isPremultiplied = true;
2079         }
2080 }
2081
2082 void
2083 _BitmapImpl::SetAsNonpremultiplied(void)
2084 {
2085         if (IS_INSTANCE_VALID)
2086         {
2087                 this->_sharedItem->isMutable = true;
2088                 this->_sharedItem->nativeBitmap->__isPremultiplied = false;
2089         }
2090 }
2091
2092 result
2093 _BitmapImpl::ConvertToNonpremultiplied(Bitmap& bitmap, bool forceConversion)
2094 {
2095         _BitmapImpl* pImpl = null;
2096
2097         // bitmap verification
2098         {
2099                 SysTryReturn(NID_GRP, &bitmap, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
2100
2101                 pImpl = _BitmapImpl::GetInstance(bitmap);
2102
2103                 SysTryReturn(NID_GRP, IS_BITMAPIMPL_VALID(pImpl), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
2104         }
2105
2106         if (!forceConversion)
2107         {
2108                 SysTryReturn(NID_GRP, !pImpl->_sharedItem->isMutable, E_INVALID_CONDITION, E_INVALID_CONDITION, "[E_INVALID_CONDITION] The given bitmap is already non-premultipied");
2109         }
2110
2111         {
2112                 BufferInfo bi;
2113
2114                 if (pImpl->Lock(bi) == E_SUCCESS)
2115                 {
2116                         _Util::Pixmap dstImage(bi.width, bi.height, bi.bitsPerPixel, (void*)bi.pPixels, bi.pitch);
2117                         dstImage.isPremultiplied = true;
2118                         dstImage.ConvertNonpremultiplied();
2119
2120                         pImpl->Unlock();
2121                 }
2122
2123                 pImpl->_sharedItem->isMutable = true;
2124                 pImpl->_sharedItem->nativeBitmap->__isPremultiplied = false;
2125
2126                 //?? this->_sharedItem->scaledNativeBitmap
2127         }
2128
2129         return E_SUCCESS;
2130 }
2131
2132 _BitmapImpl*&
2133 _BitmapImpl::_GetBitmapImpl(Bitmap* pBitmap)
2134 {
2135         return pBitmap->__pImpl;
2136 }
2137
2138 _BitmapImpl*
2139 _BitmapImpl::GetInstance(Bitmap& bitmap)
2140 {
2141         return (&bitmap != null) ? bitmap.__pImpl : null;
2142 }
2143
2144 const _BitmapImpl*
2145 _BitmapImpl::GetInstance(const Bitmap& bitmap)
2146 {
2147         return (&bitmap != null) ? bitmap.__pImpl : null;
2148 }
2149
2150 bool
2151 _BitmapImpl::__CheckValidity(bool canBufferExpand)
2152 {
2153         if (this->_sharedItem.get())
2154         {
2155                 if (this->_sharedItem->nativeBitmap->IsValid())
2156                 {
2157                         return true;
2158                 }
2159
2160                 if (!this->_sharedItem->associated.fileName.IsEmpty())
2161                 {
2162                         if (canBufferExpand)
2163                         {
2164                                 if (!__RealizeBuffer())
2165                                 {
2166                                         // linkedFileName does not exist or is not a image file.
2167                                         this->Construct(Dimension(1, 1), BITMAP_PIXEL_FORMAT_ARGB8888);
2168                                 }
2169
2170                                 this->_sharedItem->associated.fileName.Clear();
2171                         }
2172
2173                         return true;
2174                 }
2175         }
2176
2177         return false;
2178 }
2179
2180 bool
2181 _BitmapImpl::__RealizeBuffer(void)
2182 {
2183         int imageWidth = 0;
2184         int imageHeight = 0;
2185
2186         Tizen::Media::MediaPixelFormat format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
2187
2188         // The following does not consider the case of big-endian
2189         switch (this->_sharedItem->associated.pixelFormat)
2190         {
2191         case BITMAP_PIXEL_FORMAT_RGB565:
2192                 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGB565LE;
2193                 break;
2194         case BITMAP_PIXEL_FORMAT_R8G8B8A8:
2195                 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGBA8888;
2196                 break;
2197         case BITMAP_PIXEL_FORMAT_ARGB8888:
2198         default:
2199                 format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
2200                 break;
2201         }
2202
2203         std::auto_ptr<ByteBuffer> pImageBuffer(Tizen::Media::_ImageDecoder::DecodeToBufferN(this->_sharedItem->associated.fileName, format, imageWidth, imageHeight));
2204
2205         if (pImageBuffer.get() == null)
2206         {
2207                 return false;
2208         }
2209
2210         std::auto_ptr<_BitmapImpl> pTempBitmapImpl(_BitmapImpl::GetNonScaledBitmapImplN(*pImageBuffer, Dimension(imageWidth, imageHeight), this->_sharedItem->associated.pixelFormat));
2211
2212         if (pTempBitmapImpl.get() == null || pTempBitmapImpl->_sharedItem.get() == null)
2213         {
2214                 return false;
2215         }
2216
2217         pImageBuffer.reset();
2218
2219         this->_sharedItem->Move(*(pTempBitmapImpl->_sharedItem.get()));
2220
2221         return true;
2222 }
2223
2224 result
2225 _BitmapImpl::__Scale(const float width, const float height)
2226 {
2227         result r = E_SUCCESS;
2228
2229         _Util::Dimension<float> vcUtilDimF = { width, height };
2230         _BitmapCoordinateHolder tempCoordinateHolder;
2231
2232         tempCoordinateHolder.ResetFromVc(vcUtilDimF);
2233
2234         Dimension vcDim(tempCoordinateHolder.size.vcInt.w, tempCoordinateHolder.size.vcInt.h);
2235
2236         if (_ResUtil::NeedToConvertCoord())
2237         {
2238                 if (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get())
2239                 {
2240                         r = this->_sharedItem->nativeBitmap->Scale(vcDim);
2241
2242                         if (!IsFailed(r))
2243                         {
2244                                 Dimension pcDim(tempCoordinateHolder.size.pcInt.w, tempCoordinateHolder.size.pcInt.h);
2245
2246                                 r = this->_sharedItem->scaledNativeBitmap->Scale(pcDim);
2247
2248                                 if (!IsFailed(r))
2249                                 {
2250                                         _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
2251                                 }
2252                                 // @ykahn If it fails, then how to undo its status.
2253                         }
2254                 }
2255                 else
2256                 {
2257                         Dimension pcDim(tempCoordinateHolder.size.pcInt.w, tempCoordinateHolder.size.pcInt.h);
2258
2259                         r = this->_sharedItem->nativeBitmap->Scale(pcDim);
2260                 }
2261         }
2262         else
2263         {
2264                 r = this->_sharedItem->nativeBitmap->Scale(vcDim);
2265         }
2266
2267         if (r == E_SUCCESS)
2268         {
2269                 memcpy(this->_sharedItem->coordHolder.get(), &tempCoordinateHolder, sizeof(tempCoordinateHolder));
2270         }
2271
2272         return r;
2273 }
2274
2275 void _BitmapImpl::_SharedItem::Move(_BitmapImpl::_SharedItem& source)
2276 {
2277         std::swap(this->nativeBitmap, source.nativeBitmap);
2278         std::swap(this->coordHolder, source.coordHolder);
2279         std::swap(this->lazyScaling, source.lazyScaling);
2280         std::swap(this->scaledNativeBitmap, source.scaledNativeBitmap);
2281         std::swap(this->isMutable, source.isMutable);
2282 }
2283
2284 }} // Tizen::Graphics