2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0/
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
19 * @file FGrp_BitmapImpl.cpp
20 * @brief This is the implementation file for _BitmapImpl class.
28 #include <FBaseSysLog.h>
31 #include <FGrpBitmap.h>
33 #include <FMedia_ImageDecoder.h>
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"
46 using namespace Tizen::Base;
48 #define INSTANCE_IS_VALID (this && const_cast<_BitmapImpl*>(this)->__CheckValidity(true))
49 #define IS_INSTANCE_VALID (this && const_cast<_BitmapImpl*>(this)->__CheckValidity(false))
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))
59 _CheckValidityOfRectangle(const Tizen::Graphics::Rectangle& rect)
61 return ((rect.width > 0) && (rect.height > 0));
65 _CheckValidity(const Tizen::Graphics::Rectangle& rtSrc, const Tizen::Graphics::Rectangle& rtDest)
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)
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);
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)
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);
79 if (rtSrc.y > rtDest.y + rtDest.height - 1 || rtSrc.y + rtSrc.height - 1 < rtDest.y)
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);
88 _CheckValidity(const Tizen::Graphics::FloatRectangle& rtSrc, const Tizen::Graphics::FloatRectangle& rtDest)
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)
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);
96 // check 2. is src exiting outside of dest entirely?
97 if (rtSrc.x > rtDest.x + rtDest.width || rtSrc.x + rtSrc.width < rtDest.x)
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);
102 if (rtSrc.y > rtDest.y + rtDest.height || rtSrc.y + rtSrc.height < rtDest.y)
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);
112 _GetBytesPerPixel(Tizen::Graphics::BitmapPixelFormat pixelFormat)
114 if (pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565)
118 else if (pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888 || pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8)
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)
131 scalingValue.Clear();
133 scalingValue.Push(Tizen::Graphics::_Util::MakePair(scaleWidth, scaleHeight));
135 if (quality == Tizen::Graphics::BITMAP_SCALING_QUALITY_HIGH)
137 int intWidth = int(width);
138 int intHeight = int(height);
140 int tempWidth = int(scaleWidth);
141 int tempHeight = int(scaleHeight);
143 while (intWidth > (tempWidth << 1) || intHeight > (tempHeight << 1))
145 if (intWidth > (tempWidth << 1))
150 if (intHeight > (tempHeight << 1))
155 scalingValue.Push(Tizen::Graphics::_Util::MakePair(float(tempWidth), float(tempHeight)));
162 _CheckBufferSize(const Tizen::Base::ByteBuffer& buffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat pixelFormat)
164 int bytePerPixel = _GetBytesPerPixel(pixelFormat);
166 if (bytePerPixel == 0)
168 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
171 int byteNum = buffer.GetLimit();
172 int expectedBufferSize = dim.width * dim.height * bytePerPixel;
174 SysTryReturnResult(NID_GRP, expectedBufferSize <= byteNum, E_INVALID_ARG, "A buffer size is not correct. (expected: %d, actual: %d)", expectedBufferSize, byteNum);
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)
184 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565:
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);
190 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888:
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);
196 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8:
204 _UpdateScaledBitmapEx(Tizen::Graphics::_Bitmap* pSrcBitmap, Tizen::Graphics::_Bitmap* pDstBitmap)
206 if (!(pSrcBitmap && pDstBitmap && pSrcBitmap->GetPixelColorFormat() == pDstBitmap->GetPixelColorFormat()))
211 Tizen::Graphics::BufferInfo srcBufferInfo;
212 Tizen::Graphics::BufferInfo dstBufferInfo;
215 if (pSrcBitmap->Lock(srcBufferInfo) != E_SUCCESS)
220 result r = pDstBitmap->Lock(dstBufferInfo);
223 pSrcBitmap->Unlock();
232 switch (pSrcBitmap->GetPixelColorFormat())
234 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565:
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);
242 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888:
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);
250 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8:
257 pSrcBitmap->Unlock();
258 pDstBitmap->Unlock();
263 ////////////////////////////////////////////////////////////////////////////////
266 _UpdateBitmapTimeStampInternal(void)
268 static unsigned long staticTimeStamp = 0;
272 staticTimeStamp = (staticTimeStamp == 0) ? (staticTimeStamp + 1) : staticTimeStamp;
274 return staticTimeStamp;
279 ////////////////////////////////////////////////////////////////////////////////
281 namespace Tizen { namespace Graphics
285 _GetBitmapTimeStamp(const Tizen::Graphics::_BitmapImpl& bitmap)
287 Tizen::Graphics::_Bitmap* _nativeBitmap = Tizen::Graphics::_GetBitmapEx(bitmap);
289 return (_nativeBitmap) ? _nativeBitmap->GetTimeStamp() : 0;
293 _UpdateBitmapTimeStamp(Tizen::Graphics::_BitmapImpl& bitmap)
295 Tizen::Graphics::_Bitmap* _nativeBitmap = Tizen::Graphics::_GetBitmapEx(bitmap);
299 _nativeBitmap->SetTimeStamp(_UpdateBitmapTimeStampInternal());
300 return _nativeBitmap->GetTimeStamp();
306 ////////////////////////////////////////////////////////////////////////////////
308 _BitmapImpl::_BitmapImpl(void)
310 , _sharedItem(std::tr1::shared_ptr<_SharedItem>(new (std::nothrow)_SharedItem))
312 if (this->_sharedItem.get())
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->pPostlockCallbackFunc = null;
325 this->_sharedItem->pPostlockCallbackParam = null;
327 this->_sharedItem->isMutable = true;
328 this->_sharedItem->associated.pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
329 this->_sharedItem->associated.hasBeenDetectedByUsingName = false;
330 this->_sharedItem->associated.determinedNinePatchedAtFirst = false;
332 if (this->_sharedItem->nativeBitmap.get() == null || this->_sharedItem->coordHolder.get() == null)
334 this->_sharedItem->nativeBitmap.reset();
335 this->_sharedItem->coordHolder.reset();
336 this->_sharedItem.reset();
342 _UpdateBitmapTimeStamp(*this);
344 _Util::CarveMagicKey(*this, _magicKey);
347 _BitmapImpl::~_BitmapImpl(void)
349 if (this->_sharedItem.get())
351 if (this->_sharedItem->pDestroyCallbackFunc)
353 if (this->_sharedItem.unique())
355 this->_sharedItem->pDestroyCallbackFunc(this->_sharedItem->pDestroyCallbackParam);
360 _Util::EraseMagicKey(*this, _magicKey);
364 _BitmapImpl::IsConstructed(void) const
366 return (this->_sharedItem.get() && (this->_sharedItem->nativeBitmap->IsValid() || !this->_sharedItem->associated.fileName.IsEmpty()));
370 _BitmapImpl::GetFileName(void) const
372 return (this->_sharedItem.get()) ? this->_sharedItem->associated.fileName : String();
376 _BitmapImpl::Construct(const Rectangle& vc_rect)
378 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
380 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
382 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);
384 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);
387 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
389 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
391 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
393 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
395 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
396 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
398 return this->_sharedItem->nativeBitmap->Construct(pcRect);
403 _BitmapImpl::Construct(const Dimension& vc_dim, BitmapPixelFormat pixelFormat)
405 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
407 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
410 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);
414 case BITMAP_PIXEL_FORMAT_RGB565:
415 case BITMAP_PIXEL_FORMAT_ARGB8888:
416 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
419 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
424 _Util::Dimension<int> vcDim = { vc_dim.width, vc_dim.height };
426 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
428 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
430 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
432 return this->_sharedItem->nativeBitmap->Construct(pcDim, pixelFormat);
437 _BitmapImpl::Construct(const _CanvasImpl& canvas, const Rectangle& vc_rect)
439 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
441 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
443 SysTryReturnResult(NID_GRP, &canvas, E_INVALID_ARG, "A canvas is invalid.");
444 SysTryReturnResult(NID_GRP, canvas._pNativeCanvas && canvas._pNativeCanvas->IsValid(), E_INVALID_ARG, "A canvas is invalid.");
446 Rectangle rtCanvas = canvas.GetBounds();
448 SysTryReturnResult(NID_GRP, !rtCanvas.IsEmpty(), E_INVALID_ARG, "A canvas is empty.");
450 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);
452 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);
454 Tizen::Graphics::_Canvas* pCanvasEx = canvas._pNativeCanvas;
457 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
459 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
461 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
463 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
465 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
466 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
468 return this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, pcRect);
473 _BitmapImpl::Construct(const _BitmapImpl& bitmap, const Rectangle& vc_rect)
475 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
477 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
479 SysTryReturnResult(NID_GRP, BITMAPIMPL_IS_VALID(&bitmap), E_INVALID_ARG, "The source bitmap is invalid.");
481 Rectangle rtBitmap(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
483 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);
485 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);
487 _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(bitmap);
490 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
492 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
494 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
496 result r = E_SUCCESS;
497 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
499 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
500 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
502 if (Tizen::Graphics::_IsLazyScalingBitmap(bitmap))
504 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(bitmap);
506 r = this->_sharedItem->nativeBitmap->Construct(*pSrcScaledBitmapEx, pcRect);
510 r = this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, pcRect);
518 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat)
521 return this->Construct(buffer, rq_dim, pixelFormat, true);
523 // return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_AUTO);
524 // return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_NONE);
526 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
528 SysTryReturnResult(NID_GRP, __pImpl && this->_nativeBitmap, E_OUT_OF_MEMORY, "Memory allocation failed.");
530 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);
532 SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
535 // buffer size should be verified.
536 int bytePerPixel = 0;
537 if (BITMAP_PIXEL_FORMAT_RGB565 == pixelFormat)
541 else if (BITMAP_PIXEL_FORMAT_ARGB8888 == pixelFormat || BITMAP_PIXEL_FORMAT_R8G8B8A8 == pixelFormat)
547 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
550 int byteNum = buffer.GetLimit();
551 int expectedBufferSize = rq_dim.width * rq_dim.height * bytePerPixel;
553 SysTryReturnResult(NID_GRP, expectedBufferSize <= byteNum, E_INVALID_ARG, "A buffer size is not correct.");
556 if (_ResUtil::NeedToConvertCoord())
562 pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
565 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
566 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
568 if (pc_dim.width * 2 == rq_dim.width && pc_dim.height * 2 == rq_dim.height)
570 int pitch = rq_dim.width;
572 if (pixelFormat == BITMAP_PIXEL_FORMAT_ARGB8888)
574 const unsigned long MASK = 0x00FF00FF;
576 unsigned long* pBuffer = (unsigned long*) buffer.GetPointer();
577 for (int y = 0; y < pc_dim.height; y++)
579 for (int x = 0; x < pc_dim.width; x++)
581 unsigned long add1 = (pBuffer[0] & MASK) + (pBuffer[1] & MASK) + (pBuffer[pitch] & MASK) + (pBuffer[pitch + 1] & MASK);
582 unsigned long add2 = ((pBuffer[0] >> 8) & MASK) + ((pBuffer[1] >> 8) & MASK) + ((pBuffer[pitch] >> 8) & MASK) + ((pBuffer[pitch + 1] >> 8) & MASK);
584 unsigned long pix = ((add1 >> 2) & MASK) | (((add2 >> 2) & MASK) << 8);
588 pBuffer[pitch] = pix;
589 pBuffer[pitch + 1] = pix;
596 else if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
598 const unsigned short MASK1 = 0xF81F;
599 const unsigned short MASK2 = 0x07E0;
600 const unsigned short CHROMAKEY = 0xF81F | 0x0020;
604 unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
605 unsigned short* pBufferEnd = pBuffer + rq_dim.width * rq_dim.height;
607 while (pBuffer < pBufferEnd)
609 if (*pBuffer == CHROMAKEY)
617 hasChromakey = (pBuffer < pBufferEnd);
622 ; // pass through default scaling algorithm
626 unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
628 for (int y = 0; y < pc_dim.height; y++)
630 for (int x = 0; x < pc_dim.width; x++)
632 unsigned long add1 = (unsigned long) (pBuffer[0] & MASK1) + (unsigned long) (pBuffer[1] & MASK1) + (unsigned long) (pBuffer[pitch] & MASK1) + (unsigned long) (pBuffer[pitch + 1] & MASK1);
633 unsigned long add2 = (pBuffer[0] & MASK2) + (pBuffer[1] & MASK2) + (pBuffer[pitch] & MASK2) + (pBuffer[pitch + 1] & MASK2);
635 unsigned long pix = ((add1 >> 2) & MASK1) | ((add2 >> 2) & MASK2);
639 pBuffer[pitch] = pix;
640 pBuffer[pitch + 1] = pix;
650 result r = this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
654 this->_nativeBitmap->Scale(pc_dim);
656 Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
657 Rect pc_rect(0, 0, pc_dim.width, pc_dim.height);
659 this->_coordHolder->bitmapSize.required = vc_rect;
660 this->_coordHolder->bitmapSize.phyCoord = pc_rect;
661 this->_coordHolder->bitmapSize.virCoord = vc_rect;
668 return this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
675 _BitmapImpl::Construct(const BufferInfo& bufferInfo)
677 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
679 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
681 SysTryReturnResult(NID_GRP, (bufferInfo.width > 0) && (bufferInfo.height > 0) && (bufferInfo.pitch > 0)
683 , "Invalid argument (BufferInfo::width = %d, BufferInfo::height = %d, BufferInfo::pitch = %d)"
684 , bufferInfo.width, bufferInfo.height, bufferInfo.pitch);
686 SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel > 0
688 , "Invalid argument (BufferInfo::bitsPerPixel = %d)"
689 , bufferInfo.bitsPerPixel);
691 SysTryReturnResult(NID_GRP, (bufferInfo.pixelFormat > PIXEL_FORMAT_MIN) && (bufferInfo.pixelFormat < PIXEL_FORMAT_MAX)
693 , "Invalid argument (BufferInfo::pixelFormat = %d)"
694 , bufferInfo.pixelFormat);
696 SysTryReturnResult(NID_GRP, bufferInfo.pPixels != null
698 , "Invalid argument (BufferInfo::pPixels = null)");
700 SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel == 32 || bufferInfo.bitsPerPixel == 16
701 , E_UNSUPPORTED_FORMAT
702 , "Unsupported format (BufferInfo::bitsPerPixel = %d)"
703 , bufferInfo.bitsPerPixel);
705 BitmapPixelFormat bitmapPixelFormat = BITMAP_PIXEL_FORMAT_MIN;
707 switch (bufferInfo.pixelFormat)
709 case PIXEL_FORMAT_RGB565:
710 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_RGB565;
712 case PIXEL_FORMAT_ARGB8888:
713 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
715 case PIXEL_FORMAT_R8G8B8A8:
716 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_R8G8B8A8;
722 SysTryReturnResult(NID_GRP, bitmapPixelFormat != BITMAP_PIXEL_FORMAT_MIN
723 , E_UNSUPPORTED_FORMAT
724 , "Unsupported format (BufferInfo::pixelFormat = %d)"
725 , bufferInfo.pixelFormat);
727 result r = this->Construct(static_cast<const byte*>(bufferInfo.pPixels), bufferInfo.width, bufferInfo.height, bitmapPixelFormat, bufferInfo.pitch);
729 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
731 this->_sharedItem->nativeBitmap->_SetOwnership(false);
737 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
739 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
741 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
743 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);
745 SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
747 result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
754 r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
760 _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
762 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
764 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
766 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
767 const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
769 this->_sharedItem->nativeBitmap->ScaleEx(pcDim, quality);
773 _Util::Dimension<int> pcDim = { rq_dim.width, rq_dim.height };
775 this->_sharedItem->coordHolder->ResetFromPc(pcDim);
783 _BitmapImpl::Construct(const byte* pBuffer, int bufSize, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
785 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
787 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
789 SysTryReturnResult(NID_GRP, pBuffer, E_INVALID_ARG, "The specified buffer pointer is invalid.");
791 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);
793 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
795 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);
797 _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
799 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
801 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
803 result r = this->_sharedItem->nativeBitmap->Construct(pBuffer, bufSize, rq_dim, pixelFormat);
805 if (!IsFailed(r) && _ResUtil::NeedToConvertCoord())
809 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
810 const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
812 this->_sharedItem->nativeBitmap->ScaleEx(pcDim, quality);
816 _Util::Dimension<int> pcDim = { rq_dim.width, rq_dim.height };
818 this->_sharedItem->coordHolder->ResetFromPc(pcDim);
826 _BitmapImpl::Construct(const byte* pExtBuffer, int width, int height, BitmapPixelFormat pixelFormat, int pitch)
828 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
830 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
832 SysTryReturnResult(NID_GRP, pExtBuffer, E_INVALID_ARG, "The specified buffer pointer is invalid.", width, height);
834 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);
836 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
838 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
840 int bpp = _GetBytesPerPixel(pixelFormat);
842 SysTryReturnResult(NID_GRP, bpp > 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
844 result r = this->_sharedItem->nativeBitmap->Construct(pExtBuffer, width, height, bpp * 8, pitch / bpp);
848 _Util::Dimension<int> pcDim = { width, height };
850 this->_sharedItem->coordHolder->ResetFromPc(pcDim);
857 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, BufferScaling bufferScaling)
859 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
861 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
863 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);
865 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
867 result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
874 switch (bufferScaling)
876 case BUFFER_SCALING_AUTO:
877 return this->Construct(buffer, rq_dim, pixelFormat, true);
878 case BUFFER_SCALING_NONE:
881 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BufferScaling(%d) is the invalid argument.", pixelFormat);
885 _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
887 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
889 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
891 r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
893 if (!IsFailed(r) && _ResUtil::NeedToConvertCoord())
895 this->_sharedItem->lazyScaling = 1;
898 Dimension vc_dim = rq_dim;
899 Dimension pc_dim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
901 bool isScaledBufferAvailable = false;
902 Tizen::Base::ByteBuffer scaledBuffer;
905 int scaledCapacity = _GetBytesPerPixel(pixelFormat) * (pc_dim.width * pc_dim.height);
906 SysAssert(scaledCapacity > 0);
909 isScaledBufferAvailable = (scaledBuffer.Construct(scaledCapacity) == E_SUCCESS);
912 if (isScaledBufferAvailable)
914 _ScaleBuffer(scaledBuffer, pc_dim, buffer, vc_dim, pixelFormat);
916 this->_sharedItem->scaledNativeBitmap.reset(new (std::nothrow) _Bitmap);
918 if (this->_sharedItem->scaledNativeBitmap.get())
920 if (this->_sharedItem->scaledNativeBitmap->Construct(scaledBuffer, pc_dim, pixelFormat) == E_SUCCESS)
924 // BufferInfo bufferInfo;
925 // this->_scaledNativeBitmap->Lock(bufferInfo);
926 // this->_scaledNativeBitmap->Unlock();
931 this->_sharedItem->scaledNativeBitmap.reset(null);
942 _BitmapImpl::Construct(const Tizen::Base::String& fileName, BitmapPixelFormat pixelFormat)
944 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
946 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
950 case BITMAP_PIXEL_FORMAT_RGB565:
951 case BITMAP_PIXEL_FORMAT_ARGB8888:
952 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
955 SysTryReturnResult(NID_GRP, false, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
959 SysTryReturnResult(NID_GRP, Tizen::Io::File::IsFileExist(fileName), E_INVALID_ARG, "The specified file is not found.");
961 // This function doesn't verify the specified image file.
962 this->_sharedItem->associated.fileName = fileName;
963 this->_sharedItem->associated.pixelFormat = pixelFormat;
964 this->_sharedItem->associated.hasBeenDetectedByUsingName = false;
965 this->_sharedItem->associated.determinedNinePatchedAtFirst = false;
971 _BitmapImpl::Construct(const FloatRectangle& vcRectF)
973 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
975 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
977 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);
979 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);
982 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
984 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
986 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
988 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
991 pcRect.x = _FloatToIntForPos(pcRectF.x);
992 pcRect.y = _FloatToIntForPos(pcRectF.y);
993 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
994 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
996 return this->_sharedItem->nativeBitmap->Construct(pcRect);
1001 _BitmapImpl::Construct(const FloatDimension& vcDimF, BitmapPixelFormat pixelFormat)
1003 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1005 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
1007 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);
1009 switch (pixelFormat)
1011 case BITMAP_PIXEL_FORMAT_RGB565:
1012 case BITMAP_PIXEL_FORMAT_ARGB8888:
1013 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
1016 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
1021 _Util::Dimension<float> vcUtilDimF = { vcDimF.width, vcDimF.height };
1023 this->_sharedItem->coordHolder->ResetFromVc(vcUtilDimF);
1025 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
1027 return this->_sharedItem->nativeBitmap->Construct(pcDim, pixelFormat);
1032 _BitmapImpl::Construct(const _CanvasImpl& canvas, const FloatRectangle& vcRectF)
1034 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1036 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
1038 SysTryReturnResult(NID_GRP, &canvas, E_INVALID_ARG, "A canvas is invalid.");
1039 SysTryReturnResult(NID_GRP, canvas._pNativeCanvas && canvas._pNativeCanvas->IsValid(), E_INVALID_ARG, "A canvas is invalid.");
1041 FloatRectangle rtCanvasF = canvas.GetBoundsF();
1043 SysTryReturnResult(NID_GRP, !rtCanvasF.IsEmpty(), E_INVALID_ARG, "A canvas is empty.");
1045 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);
1047 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);
1049 Tizen::Graphics::_Canvas* pCanvasEx = canvas._pNativeCanvas;
1052 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
1054 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
1056 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
1059 pcRect.x = _FloatToIntForPos(pcRectF.x);
1060 pcRect.y = _FloatToIntForPos(pcRectF.y);
1061 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
1062 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
1064 return this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, pcRect);
1069 _BitmapImpl::Construct(const _BitmapImpl& bitmap, const FloatRectangle& vcRectF)
1071 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1073 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Memory allocation failed.");
1075 SysTryReturnResult(NID_GRP, BITMAPIMPL_IS_VALID(&bitmap), E_INVALID_ARG, "The source bitmap is invalid.");
1077 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);
1079 FloatRectangle rtBitmapF(0, 0, bitmap.GetWidthF(), bitmap.GetHeightF());
1081 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);
1083 _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(bitmap);
1086 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
1088 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
1090 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
1093 pcRect.x = _FloatToIntForPos(pcRectF.x);
1094 pcRect.y = _FloatToIntForPos(pcRectF.y);
1095 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
1096 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
1098 result r = E_SUCCESS;
1100 if (Tizen::Graphics::_IsLazyScalingBitmap(bitmap))
1102 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(bitmap);
1104 r = this->_sharedItem->nativeBitmap->Construct(*pSrcScaledBitmapEx, pcRect);
1108 r = this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, pcRect);
1116 _BitmapImpl::Scale(const Dimension& vc_dim)
1118 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1120 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);
1122 if (vc_dim.width == this->GetWidth() && vc_dim.height == this->GetHeight())
1128 return this->Scale(FloatDimension(float(vc_dim.width), float(vc_dim.height)));
1133 _BitmapImpl::Scale(const FloatDimension& vcDimF)
1135 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1137 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);
1139 if (vcDimF.width == this->GetWidthF() && vcDimF.height == this->GetHeightF())
1144 _UpdateBitmapTimeStamp(*this);
1146 result r = E_SUCCESS;
1148 _Util::AccumList<_Util::Pair<float, float> > scalingValue;
1150 _GetScaleInfo(this->GetScalingQuality(), this->GetWidthF(), this->GetHeightF(), vcDimF.width, vcDimF.height, scalingValue);
1152 for (_Util::AccumList<_Util::Pair<float, float> >::Iterator iter = scalingValue.End(); iter != scalingValue.Begin(); --iter)
1154 this->__Scale((iter-1)->first, (iter-1)->second);
1161 _BitmapImpl::Merge(const Point& vcDest, const _BitmapImpl& src, const Rectangle& vcSrcRect)
1163 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1165 SysTryReturnResult(NID_GRP, &src && src._sharedItem.get(), E_INVALID_ARG, "The source bitmap is invalid.");
1167 SysTryReturnResult(NID_GRP, src._sharedItem->nativeBitmap->IsValid(), E_INVALID_ARG, "The source bitmap is invalid.");
1169 SysTryReturnResult(NID_GRP, &vcSrcRect, E_INVALID_ARG, "The source rectangle is invalid.");
1170 SysTryReturnResult(NID_GRP, &vcDest, E_INVALID_ARG, "The destination position is invalid.");
1171 SysTryReturnResult(NID_GRP, vcDest.x >= 0 && vcDest.y >= 0, E_OUT_OF_RANGE, "The argument is out of range. (dest(x:%d,y:%d)).", vcDest.x, vcDest.y);
1172 SysTryReturnResult(NID_GRP, vcSrcRect.x >= 0 && vcSrcRect.y >= 0, E_OUT_OF_RANGE, "The argument is out of range. (source(x:%d,y:%d)).", vcSrcRect.x, vcSrcRect.y);
1174 SysTryReturnResult(NID_GRP, (vcSrcRect.width >= 0) && (vcSrcRect.height >= 0), E_INVALID_ARG, "The given rectangle(width:%d,height:%d) is invalid.", vcSrcRect.width, vcSrcRect.height);
1176 if ((vcSrcRect.width == 0) || (vcSrcRect.height == 0))
1182 Rectangle rtBitmap(0, 0, src.GetWidth(), src.GetHeight());
1183 SysTryReturnResult(NID_GRP, _CheckValidity(vcSrcRect, rtBitmap), E_OUT_OF_RANGE, "The argument is out of range. (srcRect(x:%d,y:%d,w:%d,h:%d)).", vcSrcRect.x, vcSrcRect.y, vcSrcRect.width, vcSrcRect.height);
1185 return this->Merge(FloatPoint(float(vcDest.x), float(vcDest.y)), src, FloatRectangle(float(vcSrcRect.x), float(vcSrcRect.y), float(vcSrcRect.width), float(vcSrcRect.height)));
1190 _BitmapImpl::Merge(const FloatPoint& destVcPosF, const _BitmapImpl& srcBitmap, const FloatRectangle& srcVcRectF)
1192 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1194 SysTryReturnResult(NID_GRP, &srcBitmap && srcBitmap._sharedItem.get(), E_INVALID_ARG, "The source bitmap is invalid.");
1196 SysTryReturnResult(NID_GRP, srcBitmap._sharedItem->nativeBitmap->IsValid(), E_INVALID_ARG, "The source bitmap is invalid.");
1198 SysTryReturnResult(NID_GRP, &srcVcRectF, E_INVALID_ARG, "The source rectangle is invalid.");
1199 SysTryReturnResult(NID_GRP, &destVcPosF, E_INVALID_ARG, "The destination position is invalid.");
1200 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);
1201 SysTryReturnResult(NID_GRP, srcVcRectF.x >= 0.0f && srcVcRectF.y >= 0.0f, E_OUT_OF_RANGE, "The argument is out of range. (source(x:%f,y:%f)).", srcVcRectF.x, srcVcRectF.y);
1203 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);
1205 if ((srcVcRectF.width == 0.0f) || (srcVcRectF.height == 0.0f))
1210 FloatRectangle rtBitmapF(0, 0, srcBitmap.GetWidthF(), srcBitmap.GetHeightF());
1211 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);
1213 _UpdateBitmapTimeStamp(*this);
1215 _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(srcBitmap);
1216 _Bitmap* pDstBitmapEx = this->_sharedItem->nativeBitmap.get();
1218 Point destVcPos(_FloatToIntForPos(destVcPosF.x), _FloatToIntForPos(destVcPosF.y));
1219 Rectangle srcVcRect;
1221 srcVcRect.x = _FloatToIntForPos(srcVcRectF.x);
1222 srcVcRect.y = _FloatToIntForPos(srcVcRectF.y);
1223 srcVcRect.width = _FloatToIntForPos(srcVcRectF.GetBottomRight().x - srcVcRectF.GetTopLeft().x);
1224 srcVcRect.height= _FloatToIntForPos(srcVcRectF.GetBottomRight().y - srcVcRectF.GetTopLeft().y);
1226 if (_ResUtil::NeedToConvertCoord())
1228 FloatPoint destPcPosF = _ResUtil::ConvertToPhyCoord(destVcPosF);
1229 FloatRectangle srcPcRectF = _ResUtil::ConvertToPhyCoord(srcVcRectF);
1231 Point destPcPos(_FloatToIntForPos(destPcPosF.x), _FloatToIntForPos(destPcPosF.y));
1232 Rectangle srcPcRect;
1234 srcPcRect.x = _FloatToIntForPos(srcPcRectF.x);
1235 srcPcRect.y = _FloatToIntForPos(srcPcRectF.y);
1236 srcPcRect.width = _FloatToIntForPos(srcPcRectF.GetBottomRight().x - srcPcRectF.GetTopLeft().x);
1237 srcPcRect.height= _FloatToIntForPos(srcPcRectF.GetBottomRight().y - srcPcRectF.GetTopLeft().y);
1240 case 0: scaled bitmap -> scaled bitmap
1242 case 1: scaled bitmap -> lazy scaled bitmap
1243 merge level 0 from the scaled source bitmap
1244 merge level 0(src) and level 1(dst)
1245 case 2: lazy scaled bitmap -> scaled bitmap
1246 merge level 1(src) and level 0(dst)
1247 case 3: lazy scaled bitmap -> lazy scaled bitmap
1248 merge level 0 (using virtual coordinate)
1249 merge level 1 (using physical coordinate)
1251 int caseNo = (Tizen::Graphics::_IsLazyScalingBitmap(srcBitmap)) ? 2 : 0;
1252 caseNo += (Tizen::Graphics::_IsLazyScalingBitmap(*this)) ? 1 : 0;
1256 case 0: // source: pre-scale, destination: pre-scale --> merge by using the physical coordinate
1258 return pDstBitmapEx->Merge(destPcPos, *pSrcBitmapEx, srcPcRect);
1260 case 1: // source: pre-scale --> level0 bitmap: merge after enlarging, level1 bitmap: merge from source directly
1262 result r = E_SUCCESS;
1266 _Bitmap srcResizedBitmap;
1270 srcVcDim.width = static_cast<int>(srcBitmap._sharedItem->coordHolder->size.vcFloatActual.w);
1271 srcVcDim.height = static_cast<int>(srcBitmap._sharedItem->coordHolder->size.vcFloatActual.h);
1273 r = srcResizedBitmap.Construct(srcVcDim, pSrcBitmapEx->GetPixelColorFormat());
1275 SysTryReturnResult(NID_GRP, !IsFailed(r), E_OUT_OF_MEMORY, "Memory allocation failed.");
1278 _UpdateScaledBitmapEx(pSrcBitmapEx, &srcResizedBitmap);
1280 r = pDstBitmapEx->Merge(destVcPos, srcResizedBitmap, srcVcRect);
1284 if (!IsFailed(r) && this->_sharedItem->scaledNativeBitmap.get())
1286 return this->_sharedItem->scaledNativeBitmap->Merge(destPcPos, *pSrcBitmapEx, srcPcRect);
1291 case 2: // destination: pre-scale --> merge from the level1 bitmap of source
1293 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(srcBitmap);
1295 SysTryReturnResult(NID_GRP, pSrcScaledBitmapEx != null, E_INVALID_ARG, "The source bitmap is invalid.");
1297 return pDstBitmapEx->Merge(destPcPos, *pSrcScaledBitmapEx, srcPcRect);
1299 case 3: // source: lazy-scale, destination: lazy-scale --> merge between level0, merge between level1
1301 result r = pDstBitmapEx->Merge(destVcPos, *pSrcBitmapEx, srcVcRect);
1303 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(srcBitmap);
1305 if (this->_sharedItem->scaledNativeBitmap.get() && pSrcScaledBitmapEx)
1307 this->_sharedItem->scaledNativeBitmap->Merge(destPcPos, *pSrcScaledBitmapEx, srcPcRect);
1314 return E_INVALID_ARG;
1319 return pDstBitmapEx->Merge(destVcPos, *pSrcBitmapEx, srcVcRect);
1322 // for removing compiler warnings
1323 return E_OPERATION_FAILED;
1327 _BitmapImpl::GetHeight() const
1329 if (!(INSTANCE_IS_VALID))
1331 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1335 return this->_sharedItem->coordHolder->size.vcInt.h;
1339 _BitmapImpl::GetHeightF(void) const
1341 if (!(INSTANCE_IS_VALID))
1343 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1347 return this->_sharedItem->coordHolder->size.vcFloat.h;
1351 _BitmapImpl::GetActualHeight(void) const
1353 if (!(INSTANCE_IS_VALID))
1355 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1359 return this->_sharedItem->coordHolder->size.vcFloatActual.h;
1363 _BitmapImpl::GetWidth() const
1365 if (!(INSTANCE_IS_VALID))
1367 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1371 return this->_sharedItem->coordHolder->size.vcInt.w;
1375 _BitmapImpl::GetWidthF(void) const
1377 if (!(INSTANCE_IS_VALID))
1379 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1383 return this->_sharedItem->coordHolder->size.vcFloat.w;
1387 _BitmapImpl::GetActualWidth(void) const
1389 if (!(INSTANCE_IS_VALID))
1391 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1395 return this->_sharedItem->coordHolder->size.vcFloatActual.w;
1399 _BitmapImpl::GetBitsPerPixel() const
1401 if (!(INSTANCE_IS_VALID))
1403 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1407 return this->_sharedItem->nativeBitmap->GetBitsPerPixel();
1411 _BitmapImpl::GetPixelColorFormat() const
1413 if (!(INSTANCE_IS_VALID))
1415 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1416 return BITMAP_PIXEL_FORMAT_MAX;
1419 return this->_sharedItem->nativeBitmap->GetPixelColorFormat();
1423 _BitmapImpl::SetMaskingColor(const Color* pColor)
1425 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1427 _UpdateBitmapTimeStamp(*this);
1429 return this->_sharedItem->nativeBitmap->SetMaskingColor(pColor);
1433 _BitmapImpl::GetMaskingColor(Color& color) const
1435 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1437 return this->_sharedItem->nativeBitmap->GetMaskingColor(color);
1441 _BitmapImpl::SetAlphaConstant(int opacity)
1443 if (INSTANCE_IS_VALID)
1445 _UpdateBitmapTimeStamp(*this);
1447 this->_sharedItem->nativeBitmap->SetAlphaConstant(opacity);
1452 _BitmapImpl::GetAlphaConstant(void) const
1454 return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetAlphaConstant() : -1;
1458 _BitmapImpl::SetScalingQuality(BitmapScalingQuality quality)
1460 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1464 case BITMAP_SCALING_QUALITY_LOW:
1465 case BITMAP_SCALING_QUALITY_MID:
1466 case BITMAP_SCALING_QUALITY_HIGH:
1469 return E_INVALID_ARG;
1472 _UpdateBitmapTimeStamp(*this);
1474 this->_sharedItem->nativeBitmap->SetScalingQuality(quality);
1479 BitmapScalingQuality
1480 _BitmapImpl::GetScalingQuality(void) const
1482 return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetScalingQuality() : BITMAP_SCALING_QUALITY_LOW;
1486 _BitmapImpl::IsNinePatchedBitmap(void) const
1489 if (!(INSTANCE_IS_VALID))
1491 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1495 _Bitmap* pRefBitmap = (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get()) ? this->_sharedItem->scaledNativeBitmap.get() : this->_sharedItem->nativeBitmap.get();
1497 return pRefBitmap->IsNinePatchedBitmap();
1499 if (!(IS_INSTANCE_VALID))
1501 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1505 const Tizen::Base::String& associatedFileName = this->_sharedItem->associated.fileName;
1507 if (associatedFileName.IsEmpty())
1509 _Bitmap* pRefBitmap = (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get()) ? this->_sharedItem->scaledNativeBitmap.get() : this->_sharedItem->nativeBitmap.get();
1511 return pRefBitmap->IsNinePatchedBitmap();
1515 return HasNinePatchedBitmapTag(associatedFileName);
1521 _BitmapImpl::SetAsImmutable(void)
1523 if (INSTANCE_IS_VALID)
1525 if (this->_sharedItem->isMutable)
1529 if (this->Lock(bi) == E_SUCCESS)
1531 _Util::Pixmap dstImage(bi.width, bi.height, bi.bitsPerPixel, (void*)bi.pPixels, bi.pitch);
1532 dstImage.ConvertPremultiplied();
1537 this->_sharedItem->isMutable = false;
1538 this->_sharedItem->nativeBitmap->__isPremultiplied = true;
1540 //?? this->_sharedItem->scaledNativeBitmap
1546 _BitmapImpl::IsMutable(void) const
1548 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, false, "This instance is not constructed yet.");
1550 return this->_sharedItem->isMutable;
1554 _BitmapImpl::Lock(BufferInfo& info, long timeout)
1556 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1558 _UpdateBitmapTimeStamp(*this);
1560 return this->_sharedItem->nativeBitmap->Lock(info, timeout);
1564 _BitmapImpl::Unlock()
1566 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1568 result r = this->_sharedItem->nativeBitmap->Unlock();
1570 _UpdateBitmapTimeStamp(*this);
1572 if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1574 if (this->_sharedItem->scaledNativeBitmap.get())
1576 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1577 this->_sharedItem->scaledNativeBitmap->UpdateOpaqueInfo();
1585 _BitmapImpl::LockFast(BufferInfo& info, long timeout)
1587 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1589 _UpdateBitmapTimeStamp(*this);
1591 return this->_sharedItem->nativeBitmap->LockFast(info, timeout);
1595 _BitmapImpl::UnlockFast()
1597 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1599 result r = this->_sharedItem->nativeBitmap->UnlockFast();
1601 _UpdateBitmapTimeStamp(*this);
1603 if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1605 if (this->_sharedItem->scaledNativeBitmap.get())
1607 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1615 _BitmapImpl::CheckNinePatchedBitmapStrictly(const Bitmap& bitmap)
1617 const _BitmapImpl* pThis = _BitmapImpl::GetInstance(bitmap);
1619 if (!(IS_BITMAPIMPL_VALID(pThis)))
1621 SysLog(NID_GRP, "[E_OPERATION_FAILED] The given bitmap is not constructed yet.");
1625 if (pThis->_sharedItem->associated.hasBeenDetectedByUsingName)
1627 return pThis->_sharedItem->associated.determinedNinePatchedAtFirst;
1630 const Tizen::Base::String& associatedFileName = pThis->_sharedItem->associated.fileName;
1632 if (associatedFileName.IsEmpty())
1634 _Bitmap* pRefBitmap = (pThis->_sharedItem->lazyScaling && pThis->_sharedItem->scaledNativeBitmap.get()) ? pThis->_sharedItem->scaledNativeBitmap.get() : pThis->_sharedItem->nativeBitmap.get();
1636 return pRefBitmap->IsNinePatchedBitmap(true);
1640 bool ret = HasNinePatchedBitmapTag(associatedFileName);
1642 pThis->_sharedItem->associated.hasBeenDetectedByUsingName = true;
1643 pThis->_sharedItem->associated.determinedNinePatchedAtFirst = ret;
1650 _BitmapImpl::_SetCallback(void (* DestroyCallback)(void*), void* pDestroyCallbackParam,
1651 void (* LockCallback)(void*), void* pLockCallbackParam,
1652 void (* UnlockCallback)(void*), void* pUnlockCallbackParam,
1653 void (* PostlockCallback)(BufferInfo&, void*), void* pPostlockCallbackParam)
1655 if (!(INSTANCE_IS_VALID))
1657 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1661 _UpdateBitmapTimeStamp(*this);
1663 this->_sharedItem->pDestroyCallbackFunc = DestroyCallback;
1664 this->_sharedItem->pDestroyCallbackParam = pDestroyCallbackParam;
1666 this->_sharedItem->pLockCallbackFunc = LockCallback;
1667 this->_sharedItem->pLockCallbackParam = pLockCallbackParam;
1669 this->_sharedItem->pUnlockCallbackFunc = UnlockCallback;
1670 this->_sharedItem->pUnlockCallbackParam = pUnlockCallbackParam;
1672 this->_sharedItem->pPostlockCallbackFunc = PostlockCallback;
1673 this->_sharedItem->pPostlockCallbackParam = pPostlockCallbackParam;
1675 if (this->_sharedItem->nativeBitmap.get())
1677 this->_sharedItem->nativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam, PostlockCallback, pPostlockCallbackParam);
1680 if (this->_sharedItem->scaledNativeBitmap.get())
1682 this->_sharedItem->scaledNativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam, PostlockCallback, pPostlockCallbackParam);
1689 _BitmapImpl::GetExpandedBitmapN(const Bitmap& ninePatchedBitmap, int width, int height)
1691 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);
1693 SysTryReturn(NID_GRP, &ninePatchedBitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1695 const _BitmapImpl* pSrcBitmapImpl = _BitmapImpl::GetInstance(ninePatchedBitmap);
1697 SysTryReturn(NID_GRP, BITMAPIMPL_IS_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1699 SysTryReturn(NID_GRP, pSrcBitmapImpl->IsNinePatchedBitmap(), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is not a nine-patched bitmap");
1701 BitmapPixelFormat pixelFormat = pSrcBitmapImpl->GetPixelColorFormat();
1703 switch (pixelFormat)
1705 case BITMAP_PIXEL_FORMAT_RGB565:
1706 case BITMAP_PIXEL_FORMAT_ARGB8888:
1709 SysTryReturn(NID_GRP, false, null, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] Pixel format of the given bitmap is invalid (%d)", pixelFormat);
1713 return _BitmapImpl::GetExpandedBitmapFN(ninePatchedBitmap, float(width), float (height));
1717 _BitmapImpl::GetExpandedBitmapFN(const Bitmap& ninePatchedBitmap, float width, float height)
1719 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);
1721 SysTryReturn(NID_GRP, &ninePatchedBitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1723 const _BitmapImpl* pSrcBitmapImpl = _BitmapImpl::GetInstance(ninePatchedBitmap);
1725 SysTryReturn(NID_GRP, BITMAPIMPL_IS_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1727 SysTryReturn(NID_GRP, pSrcBitmapImpl->IsNinePatchedBitmap(), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is not a nine-patched bitmap");
1729 BitmapPixelFormat pixelFormat = pSrcBitmapImpl->GetPixelColorFormat();
1731 switch (pixelFormat)
1733 case BITMAP_PIXEL_FORMAT_RGB565:
1734 case BITMAP_PIXEL_FORMAT_ARGB8888:
1737 SysTryReturn(NID_GRP, false, null, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] Pixel format of the given bitmap is invalid (%d)", pixelFormat);
1741 std::auto_ptr<Bitmap> expandedBitmap(new (std::nothrow) Bitmap);
1743 SysTryReturn(NID_GRP, expandedBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1745 result r = expandedBitmap->Construct(FloatDimension(width, height), pixelFormat);
1747 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1749 _BitmapImpl* pDstBitmapImpl = _BitmapImpl::GetInstance(*expandedBitmap.get());
1751 SysAssert(pDstBitmapImpl != null);
1754 _Util::LockManager srcBitmap(*pSrcBitmapImpl);
1755 _Util::LockManager dstBitmap(*pDstBitmapImpl);
1757 SysTryReturn(NID_GRP, srcBitmap.IsValid(), null, srcBitmap.GetResult(), "[%s] Buffer locking of the source bitmap failed", srcBitmap.GetResult());
1758 SysTryReturn(NID_GRP, dstBitmap.IsValid(), null, dstBitmap.GetResult(), "[%s] Buffer locking of the target bitmap failed", dstBitmap.GetResult());
1760 if (dstBitmap.GetBufferInfo().width < srcBitmap.GetBufferInfo().width - 2 ||
1761 dstBitmap.GetBufferInfo().height < srcBitmap.GetBufferInfo().height - 2)
1763 // down-scales from the source bitmap only
1764 const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1765 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1767 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1769 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1771 Rectangle sourRect(1, 1, srcBufferInfo.width - 2, srcBufferInfo.height - 2);
1772 Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
1774 unsigned char* pSrcPixels = (unsigned char*) srcBufferInfo.pPixels + sourRect.y * srcBufferInfo.pitch + sourRect.x * (srcBufferInfo.bitsPerPixel / 8);
1775 _Util::Pixmap srcImage(sourRect.width, sourRect.height, srcBufferInfo.bitsPerPixel, (void*) pSrcPixels, srcBufferInfo.pitch);
1777 Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1781 const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1782 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1784 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1786 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1788 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
1790 Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
1792 // assert(pSrcBitmapImpl->_nativeBitmap);
1793 r = _Util::GetPatchList(boundsList, destRect, *pSrcBitmapImpl->_sharedItem->nativeBitmap.get());
1795 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] _Util::GetPatchList() failed (error = %#x)", r);
1797 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
1799 while (iter != boundsList.End())
1801 Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
1802 Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
1805 unsigned char* pSrcPixels = (unsigned char*) srcBufferInfo.pPixels + sourRect.y * srcBufferInfo.pitch + sourRect.x * (srcBufferInfo.bitsPerPixel / 8);
1806 _Util::Pixmap srcImage(sourRect.width, sourRect.height, srcBufferInfo.bitsPerPixel, (void*) pSrcPixels, srcBufferInfo.pitch);
1808 Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1816 return expandedBitmap.release();
1820 _BitmapImpl::GetColorReplacedBitmapN(const Bitmap& bitmap, const Color& replacedColor, const Color& newColor)
1822 SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1824 std::auto_ptr<Bitmap> pRetBitmap;
1827 Bitmap* pSrcBitmap = const_cast<Bitmap*>(&bitmap);
1830 pSrcBitmap->Lock(biSrc);
1832 pRetBitmap.reset(_BitmapUtil::CreateBitmapN(Dimension(biSrc.width, biSrc.height), biSrc.bitsPerPixel));
1834 if (pRetBitmap.get())
1837 pRetBitmap->Lock(biDst);
1839 if ((biSrc.pitch == biDst.pitch) && (biSrc.height == biDst.height))
1841 memcpy(biDst.pPixels, biSrc.pPixels, biDst.pitch * biDst.height);
1844 pRetBitmap->Unlock();
1847 pSrcBitmap->Unlock();
1849 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] New bitmap construction failed");
1852 BufferInfo bufferInfo;
1854 result r = pRetBitmap->Lock(bufferInfo);
1856 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap cannot retrieve the own buffer address");
1858 if (bufferInfo.bitsPerPixel == 32)
1860 typedef unsigned long Pixel;
1862 Pixel keyColor = replacedColor.GetRGB32() & 0x00FFFFFF;
1863 Pixel chgColor = newColor.GetRGB32() & 0x00FFFFFF;
1864 Pixel* pBuffer = reinterpret_cast<Pixel*>(bufferInfo.pPixels);
1865 int padding = bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel - bufferInfo.width;
1867 Pixel keyAlpha = (newColor.GetRGB32() & 0xFF000000) >> 24;
1868 keyAlpha += (keyAlpha >> 7);
1872 for (int y = 0; y < bufferInfo.height; y++)
1874 for (int x = 0; x < bufferInfo.width; x++)
1876 // if buffer.rgb = replacedColor.rgb then begin
1877 // buffer.a <- buffer.a * newColor.a;
1878 // buffer.r <- newColor.r;
1879 // buffer.g <- newColor.g;
1880 // buffer.b <- newColor.b;
1883 if ((*pBuffer & 0x00FFFFFF) == keyColor)
1885 Pixel alpha = (*pBuffer >> 8) & 0x00FF0000;
1886 alpha = (alpha * keyAlpha) & 0xFF000000;
1888 *pBuffer = alpha | chgColor;
1899 for (int y = 0; y < bufferInfo.height; y++)
1901 for (int x = 0; x < bufferInfo.width; x++)
1903 // if buffer.rgb = replacedColor.rgb then begin
1904 // buffer.a <- buffer.a;
1905 // buffer.r <- newColor.r;
1906 // buffer.g <- newColor.g;
1907 // buffer.b <- newColor.b;
1910 if ((*pBuffer & 0x00FFFFFF) == keyColor)
1912 *pBuffer = (*pBuffer & 0xFF000000) | chgColor;
1922 else if (bufferInfo.bitsPerPixel == 16)
1924 typedef unsigned short Pixel;
1928 Pixel* pBuffer = reinterpret_cast<Pixel*>(bufferInfo.pPixels);
1929 int padding = bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel - bufferInfo.width;
1932 unsigned long color32 = replacedColor.GetRGB32();
1933 _Effect::Func::ConvertColorFormatFast(&keyColor, &color32);
1937 unsigned long color32 = newColor.GetRGB32() & 0x00FFFFFF;
1938 _Effect::Func::ConvertColorFormatFast(&chgColor, &color32);
1941 for (int y = 0; y < bufferInfo.height; y++)
1943 for (int x = 0; x < bufferInfo.width; x++)
1945 if (*pBuffer == keyColor)
1947 *pBuffer = chgColor;
1961 pRetBitmap->Unlock();
1963 return pRetBitmap.release();
1967 _BitmapImpl::CloneN(const Bitmap& bitmap)
1969 const _BitmapImpl* pSrcBitmapImpl = null;
1970 _BitmapImpl* pDstBitmapImpl = null;
1972 // source bitmap verification
1974 SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1976 pSrcBitmapImpl = _BitmapImpl::GetInstance(bitmap);
1978 SysTryReturn(NID_GRP, IS_BITMAPIMPL_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1981 // destination bitmap allocation
1982 std::auto_ptr<Bitmap> pRetBitmap(new (std::nothrow) Bitmap);
1985 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1987 pDstBitmapImpl = _BitmapImpl::GetInstance(*pRetBitmap.get());
1989 SysTryReturn(NID_GRP, pDstBitmapImpl && pDstBitmapImpl->_sharedItem.get() && !pDstBitmapImpl->_sharedItem->nativeBitmap->IsValid(), null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap is invalid");
1992 pDstBitmapImpl->_sharedItem = pSrcBitmapImpl->_sharedItem;
1994 return pRetBitmap.release();
1998 _BitmapImpl::GetNonScaledBitmapImplN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
2000 return _NonScale::CreateBitmapN(buffer, dim, pixelFormat);
2004 _BitmapImpl::GetNonScaledBitmapN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
2006 _BitmapImpl* pBitmapImpl = _BitmapImpl::GetNonScaledBitmapImplN(buffer, dim, pixelFormat);
2008 if (pBitmapImpl == null)
2013 return Tizen::Graphics::_BitmapUtil::CreateBitmapN(pBitmapImpl);
2017 _BitmapImpl::GetNonScaledBitmapN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat, const FloatDimension& logicalSize)
2019 Bitmap* pBitmap = GetNonScaledBitmapN(buffer, dim, pixelFormat);
2023 _BitmapImpl* pBitmapImpl = _BitmapImpl::GetInstance(*pBitmap);
2027 pBitmapImpl->_sharedItem->coordHolder->size.vcFloat.w = logicalSize.width;
2028 pBitmapImpl->_sharedItem->coordHolder->size.vcFloat.h = logicalSize.height;
2041 _BitmapImpl::HasNinePatchedBitmapTag(Tizen::Base::String fileName)
2043 const wchar_t* NINE_PATCHED_TAG = L".#.png"; // it must consist of lower-case characters
2044 const int NINE_PATCHED_TAG_LENGTH = 6;
2048 static wchar_t ToLower(wchar_t ch)
2050 return (ch >= L'A' && ch <= L'Z') ? ch + 'a' - 'A' : ch;
2054 _Util::String tempStr(fileName.GetPointer(), fileName.GetLength());
2056 while (tempStr.length > 0 && tempStr.pStart[tempStr.length - 1] == L' ')
2061 _Util::String testStr(tempStr.pStart, tempStr.length, tempStr.length - NINE_PATCHED_TAG_LENGTH, NINE_PATCHED_TAG_LENGTH);
2063 if (testStr.length == NINE_PATCHED_TAG_LENGTH)
2065 for (int i = 0; i < NINE_PATCHED_TAG_LENGTH; i++)
2067 if (Temp::ToLower(testStr.pStart[i]) == NINE_PATCHED_TAG[i])
2082 _BitmapImpl::SetAsPremultiplied(void)
2084 if (IS_INSTANCE_VALID)
2086 this->_sharedItem->isMutable = false;
2087 this->_sharedItem->nativeBitmap->__isPremultiplied = true;
2092 _BitmapImpl::SetAsNonpremultiplied(void)
2094 if (IS_INSTANCE_VALID)
2096 this->_sharedItem->isMutable = true;
2097 this->_sharedItem->nativeBitmap->__isPremultiplied = false;
2102 _BitmapImpl::ConvertToNonpremultiplied(Bitmap& bitmap, bool forceConversion)
2104 _BitmapImpl* pImpl = null;
2106 // bitmap verification
2108 SysTryReturn(NID_GRP, &bitmap, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
2110 pImpl = _BitmapImpl::GetInstance(bitmap);
2112 SysTryReturn(NID_GRP, IS_BITMAPIMPL_VALID(pImpl), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
2115 if (!forceConversion)
2117 SysTryReturn(NID_GRP, !pImpl->_sharedItem->isMutable, E_INVALID_CONDITION, E_INVALID_CONDITION, "[E_INVALID_CONDITION] The given bitmap is already non-premultipied");
2123 if (pImpl->Lock(bi) == E_SUCCESS)
2125 _Util::Pixmap dstImage(bi.width, bi.height, bi.bitsPerPixel, (void*)bi.pPixels, bi.pitch);
2126 dstImage.isPremultiplied = true;
2127 dstImage.ConvertNonpremultiplied();
2132 pImpl->_sharedItem->isMutable = true;
2133 pImpl->_sharedItem->nativeBitmap->__isPremultiplied = false;
2135 //?? this->_sharedItem->scaledNativeBitmap
2142 _BitmapImpl::_GetBitmapImpl(Bitmap* pBitmap)
2144 return pBitmap->__pImpl;
2148 _BitmapImpl::GetInstance(Bitmap& bitmap)
2150 return (&bitmap != null) ? bitmap.__pImpl : null;
2154 _BitmapImpl::GetInstance(const Bitmap& bitmap)
2156 return (&bitmap != null) ? bitmap.__pImpl : null;
2160 _BitmapImpl::__CheckValidity(bool canBufferExpand)
2162 if (this->_sharedItem.get())
2164 if (this->_sharedItem->nativeBitmap->IsValid())
2169 if (!this->_sharedItem->associated.fileName.IsEmpty())
2171 if (canBufferExpand)
2173 if (!__RealizeBuffer())
2175 // linkedFileName does not exist or is not a image file.
2176 this->Construct(Dimension(1, 1), BITMAP_PIXEL_FORMAT_ARGB8888);
2179 this->_sharedItem->associated.fileName.Clear();
2190 _BitmapImpl::__RealizeBuffer(void)
2193 int imageHeight = 0;
2195 Tizen::Media::MediaPixelFormat format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
2197 // The following does not consider the case of big-endian
2198 switch (this->_sharedItem->associated.pixelFormat)
2200 case BITMAP_PIXEL_FORMAT_RGB565:
2201 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGB565LE;
2203 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
2204 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGBA8888;
2206 case BITMAP_PIXEL_FORMAT_ARGB8888:
2208 format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
2212 std::auto_ptr<ByteBuffer> pImageBuffer(Tizen::Media::_ImageDecoder::DecodeToBufferN(this->_sharedItem->associated.fileName, format, imageWidth, imageHeight));
2214 if (pImageBuffer.get() == null)
2219 std::auto_ptr<_BitmapImpl> pTempBitmapImpl(_BitmapImpl::GetNonScaledBitmapImplN(*pImageBuffer, Dimension(imageWidth, imageHeight), this->_sharedItem->associated.pixelFormat));
2221 if (pTempBitmapImpl.get() == null || pTempBitmapImpl->_sharedItem.get() == null)
2226 pImageBuffer.reset();
2228 this->_sharedItem->Move(*(pTempBitmapImpl->_sharedItem.get()));
2234 _BitmapImpl::__Scale(const float width, const float height)
2236 result r = E_SUCCESS;
2238 _Util::Dimension<float> vcUtilDimF = { width, height };
2239 _BitmapCoordinateHolder tempCoordinateHolder;
2241 tempCoordinateHolder.ResetFromVc(vcUtilDimF);
2243 Dimension vcDim(tempCoordinateHolder.size.vcInt.w, tempCoordinateHolder.size.vcInt.h);
2245 if (_ResUtil::NeedToConvertCoord())
2247 if (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get())
2249 r = this->_sharedItem->nativeBitmap->Scale(vcDim);
2253 Dimension pcDim(tempCoordinateHolder.size.pcInt.w, tempCoordinateHolder.size.pcInt.h);
2255 r = this->_sharedItem->scaledNativeBitmap->Scale(pcDim);
2259 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
2261 // @ykahn If it fails, then how to undo its status.
2266 Dimension pcDim(tempCoordinateHolder.size.pcInt.w, tempCoordinateHolder.size.pcInt.h);
2268 r = this->_sharedItem->nativeBitmap->Scale(pcDim);
2273 r = this->_sharedItem->nativeBitmap->Scale(vcDim);
2278 memcpy(this->_sharedItem->coordHolder.get(), &tempCoordinateHolder, sizeof(tempCoordinateHolder));
2284 void _BitmapImpl::_SharedItem::Move(_BitmapImpl::_SharedItem& source)
2286 std::swap(this->nativeBitmap, source.nativeBitmap);
2287 std::swap(this->coordHolder, source.coordHolder);
2288 std::swap(this->lazyScaling, source.lazyScaling);
2289 std::swap(this->scaledNativeBitmap, source.scaledNativeBitmap);
2290 std::swap(this->isMutable, source.isMutable);
2293 }} // Tizen::Graphics