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->isMutable = true;
325 this->_sharedItem->associated.pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
326 this->_sharedItem->associated.hasBeenDetectedByUsingName = false;
327 this->_sharedItem->associated.determinedNinePatchedAtFirst = false;
329 if (this->_sharedItem->nativeBitmap.get() == null || this->_sharedItem->coordHolder.get() == null)
331 this->_sharedItem->nativeBitmap.reset();
332 this->_sharedItem->coordHolder.reset();
333 this->_sharedItem.reset();
339 _UpdateBitmapTimeStamp(*this);
341 _Util::CarveMagicKey(*this, _magicKey);
344 _BitmapImpl::~_BitmapImpl(void)
346 if (this->_sharedItem.get())
348 if (this->_sharedItem->pDestroyCallbackFunc)
350 if (this->_sharedItem.unique())
352 this->_sharedItem->pDestroyCallbackFunc(this->_sharedItem->pDestroyCallbackParam);
357 _Util::EraseMagicKey(*this, _magicKey);
361 _BitmapImpl::IsConstructed(void) const
363 return (this->_sharedItem.get() && (this->_sharedItem->nativeBitmap->IsValid() || !this->_sharedItem->associated.fileName.IsEmpty()));
367 _BitmapImpl::GetFileName(void) const
369 return (this->_sharedItem.get()) ? this->_sharedItem->associated.fileName : String();
373 _BitmapImpl::Construct(const Rectangle& vc_rect)
375 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
377 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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);
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);
384 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
386 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
388 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
390 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
392 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
393 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
395 return this->_sharedItem->nativeBitmap->Construct(pcRect);
400 _BitmapImpl::Construct(const Dimension& vc_dim, BitmapPixelFormat pixelFormat)
402 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
404 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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);
411 case BITMAP_PIXEL_FORMAT_RGB565:
412 case BITMAP_PIXEL_FORMAT_ARGB8888:
413 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
416 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
421 _Util::Dimension<int> vcDim = { vc_dim.width, vc_dim.height };
423 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
425 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
427 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
429 return this->_sharedItem->nativeBitmap->Construct(pcDim, pixelFormat);
434 _BitmapImpl::Construct(const _CanvasImpl& canvas, const Rectangle& vc_rect)
436 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
438 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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.");
443 Rectangle rtCanvas = canvas.GetBounds();
445 SysTryReturnResult(NID_GRP, !rtCanvas.IsEmpty(), E_INVALID_ARG, "A canvas is empty.");
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);
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);
451 Tizen::Graphics::_Canvas* pCanvasEx = canvas._pNativeCanvas;
454 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
456 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
458 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
460 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
462 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
463 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
465 return this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, pcRect);
470 _BitmapImpl::Construct(const _BitmapImpl& bitmap, const Rectangle& vc_rect)
472 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
474 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
476 SysTryReturnResult(NID_GRP, BITMAPIMPL_IS_VALID(&bitmap), E_INVALID_ARG, "The source bitmap is invalid.");
478 Rectangle rtBitmap(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
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);
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);
484 _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(bitmap);
487 _Util::Dimension<int> vcDim = { vc_rect.width, vc_rect.height };
489 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
491 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
493 result r = E_SUCCESS;
494 Rectangle pcRect = _ResUtil::ConvertToPhyCoord(vc_rect);
496 pcRect.width = this->_sharedItem->coordHolder->size.pcInt.w;
497 pcRect.height = this->_sharedItem->coordHolder->size.pcInt.h;
499 if (Tizen::Graphics::_IsLazyScalingBitmap(bitmap))
501 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(bitmap);
503 r = this->_sharedItem->nativeBitmap->Construct(*pSrcScaledBitmapEx, pcRect);
507 r = this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, pcRect);
515 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat)
518 return this->Construct(buffer, rq_dim, pixelFormat, true);
520 // return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_AUTO);
521 // return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_NONE);
523 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
525 SysTryReturnResult(NID_GRP, __pImpl && this->_nativeBitmap, E_OUT_OF_MEMORY, "Fails to allocate memory.");
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);
529 SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
532 // buffer size should be verified.
533 int bytePerPixel = 0;
534 if (BITMAP_PIXEL_FORMAT_RGB565 == pixelFormat)
538 else if (BITMAP_PIXEL_FORMAT_ARGB8888 == pixelFormat || BITMAP_PIXEL_FORMAT_R8G8B8A8 == pixelFormat)
544 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
547 int byteNum = buffer.GetLimit();
548 int expectedBufferSize = rq_dim.width * rq_dim.height * bytePerPixel;
550 SysTryReturnResult(NID_GRP, expectedBufferSize <= byteNum, E_INVALID_ARG, "A buffer size is not correct.");
553 if (_ResUtil::NeedToConvertCoord())
559 pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
562 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
563 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
565 if (pc_dim.width * 2 == rq_dim.width && pc_dim.height * 2 == rq_dim.height)
567 int pitch = rq_dim.width;
569 if (pixelFormat == BITMAP_PIXEL_FORMAT_ARGB8888)
571 const unsigned long MASK = 0x00FF00FF;
573 unsigned long* pBuffer = (unsigned long*) buffer.GetPointer();
574 for (int y = 0; y < pc_dim.height; y++)
576 for (int x = 0; x < pc_dim.width; x++)
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);
581 unsigned long pix = ((add1 >> 2) & MASK) | (((add2 >> 2) & MASK) << 8);
585 pBuffer[pitch] = pix;
586 pBuffer[pitch + 1] = pix;
593 else if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
595 const unsigned short MASK1 = 0xF81F;
596 const unsigned short MASK2 = 0x07E0;
597 const unsigned short CHROMAKEY = 0xF81F | 0x0020;
601 unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
602 unsigned short* pBufferEnd = pBuffer + rq_dim.width * rq_dim.height;
604 while (pBuffer < pBufferEnd)
606 if (*pBuffer == CHROMAKEY)
614 hasChromakey = (pBuffer < pBufferEnd);
619 ; // pass through default scaling algorithm
623 unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
625 for (int y = 0; y < pc_dim.height; y++)
627 for (int x = 0; x < pc_dim.width; x++)
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);
632 unsigned long pix = ((add1 >> 2) & MASK1) | ((add2 >> 2) & MASK2);
636 pBuffer[pitch] = pix;
637 pBuffer[pitch + 1] = pix;
647 result r = this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
651 this->_nativeBitmap->Scale(pc_dim);
653 Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
654 Rect pc_rect(0, 0, pc_dim.width, pc_dim.height);
656 this->_coordHolder->bitmapSize.required = vc_rect;
657 this->_coordHolder->bitmapSize.phyCoord = pc_rect;
658 this->_coordHolder->bitmapSize.virCoord = vc_rect;
665 return this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
672 _BitmapImpl::Construct(const BufferInfo& bufferInfo)
674 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
676 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
678 SysTryReturnResult(NID_GRP, (bufferInfo.width > 0) && (bufferInfo.height > 0) && (bufferInfo.pitch > 0)
680 , "Invalid argument (BufferInfo::width = %d, BufferInfo::height = %d, BufferInfo::pitch = %d)"
681 , bufferInfo.width, bufferInfo.height, bufferInfo.pitch);
683 SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel > 0
685 , "Invalid argument (BufferInfo::bitsPerPixel = %d)"
686 , bufferInfo.bitsPerPixel);
688 SysTryReturnResult(NID_GRP, (bufferInfo.pixelFormat > PIXEL_FORMAT_MIN) && (bufferInfo.pixelFormat < PIXEL_FORMAT_MAX)
690 , "Invalid argument (BufferInfo::pixelFormat = %d)"
691 , bufferInfo.pixelFormat);
693 SysTryReturnResult(NID_GRP, bufferInfo.pPixels != null
695 , "Invalid argument (BufferInfo::pPixels = null)");
697 SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel == 32 || bufferInfo.bitsPerPixel == 16
698 , E_UNSUPPORTED_FORMAT
699 , "Unsupported format (BufferInfo::bitsPerPixel = %d)"
700 , bufferInfo.bitsPerPixel);
702 BitmapPixelFormat bitmapPixelFormat = BITMAP_PIXEL_FORMAT_MIN;
704 switch (bufferInfo.pixelFormat)
706 case PIXEL_FORMAT_RGB565:
707 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_RGB565;
709 case PIXEL_FORMAT_ARGB8888:
710 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
712 case PIXEL_FORMAT_R8G8B8A8:
713 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_R8G8B8A8;
719 SysTryReturnResult(NID_GRP, bitmapPixelFormat != BITMAP_PIXEL_FORMAT_MIN
720 , E_UNSUPPORTED_FORMAT
721 , "Unsupported format (BufferInfo::pixelFormat = %d)"
722 , bufferInfo.pixelFormat);
724 result r = this->Construct(static_cast<const byte*>(bufferInfo.pPixels), bufferInfo.width, bufferInfo.height, bitmapPixelFormat, bufferInfo.pitch);
726 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
728 this->_sharedItem->nativeBitmap->_SetOwnership(false);
734 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
736 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
738 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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);
742 SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
744 result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
751 r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
757 _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
759 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
761 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
763 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
764 const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
766 this->_sharedItem->nativeBitmap->ScaleEx(pcDim, quality);
770 _Util::Dimension<int> pcDim = { rq_dim.width, rq_dim.height };
772 this->_sharedItem->coordHolder->ResetFromPc(pcDim);
780 _BitmapImpl::Construct(const byte* pBuffer, int bufSize, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
782 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
784 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
786 SysTryReturnResult(NID_GRP, pBuffer, E_INVALID_ARG, "The specified buffer pointer is invalid.");
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);
790 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
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);
794 _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
796 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
798 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
800 result r = this->_sharedItem->nativeBitmap->Construct(pBuffer, bufSize, rq_dim, pixelFormat);
802 if (!IsFailed(r) && _ResUtil::NeedToConvertCoord())
806 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
807 const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
809 this->_sharedItem->nativeBitmap->ScaleEx(pcDim, quality);
813 _Util::Dimension<int> pcDim = { rq_dim.width, rq_dim.height };
815 this->_sharedItem->coordHolder->ResetFromPc(pcDim);
823 _BitmapImpl::Construct(const byte* pExtBuffer, int width, int height, BitmapPixelFormat pixelFormat, int pitch)
825 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
827 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
829 SysTryReturnResult(NID_GRP, pExtBuffer, E_INVALID_ARG, "The specified buffer pointer is invalid.", width, height);
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);
833 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
835 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
837 int bpp = _GetBytesPerPixel(pixelFormat);
839 SysTryReturnResult(NID_GRP, bpp > 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
841 result r = this->_sharedItem->nativeBitmap->Construct(pExtBuffer, width, height, bpp * 8, pitch / bpp);
845 _Util::Dimension<int> pcDim = { width, height };
847 this->_sharedItem->coordHolder->ResetFromPc(pcDim);
854 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, BufferScaling bufferScaling)
856 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
858 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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);
862 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
864 result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
871 switch (bufferScaling)
873 case BUFFER_SCALING_AUTO:
874 return this->Construct(buffer, rq_dim, pixelFormat, true);
875 case BUFFER_SCALING_NONE:
878 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BufferScaling(%d) is the invalid argument.", pixelFormat);
882 _Util::Dimension<int> vcDim = { rq_dim.width, rq_dim.height };
884 this->_sharedItem->coordHolder->ResetFromVc(vcDim);
886 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
888 r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
890 if (!IsFailed(r) && _ResUtil::NeedToConvertCoord())
892 this->_sharedItem->lazyScaling = 1;
895 Dimension vc_dim = rq_dim;
896 Dimension pc_dim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
898 bool isScaledBufferAvailable = false;
899 Tizen::Base::ByteBuffer scaledBuffer;
902 int scaledCapacity = _GetBytesPerPixel(pixelFormat) * (pc_dim.width * pc_dim.height);
903 SysAssert(scaledCapacity > 0);
906 isScaledBufferAvailable = (scaledBuffer.Construct(scaledCapacity) == E_SUCCESS);
909 if (isScaledBufferAvailable)
911 _ScaleBuffer(scaledBuffer, pc_dim, buffer, vc_dim, pixelFormat);
913 this->_sharedItem->scaledNativeBitmap.reset(new (std::nothrow) _Bitmap);
915 if (this->_sharedItem->scaledNativeBitmap.get())
917 if (this->_sharedItem->scaledNativeBitmap->Construct(scaledBuffer, pc_dim, pixelFormat) == E_SUCCESS)
921 // BufferInfo bufferInfo;
922 // this->_scaledNativeBitmap->Lock(bufferInfo);
923 // this->_scaledNativeBitmap->Unlock();
928 this->_sharedItem->scaledNativeBitmap.reset(null);
939 _BitmapImpl::Construct(const Tizen::Base::String& fileName, BitmapPixelFormat pixelFormat)
941 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
943 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
947 case BITMAP_PIXEL_FORMAT_RGB565:
948 case BITMAP_PIXEL_FORMAT_ARGB8888:
949 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
952 SysTryReturnResult(NID_GRP, false, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
956 SysTryReturnResult(NID_GRP, Tizen::Io::File::IsFileExist(fileName), E_INVALID_ARG, "The specified file is not found.");
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;
968 _BitmapImpl::Construct(const FloatRectangle& vcRectF)
970 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
972 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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);
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);
979 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
981 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
983 // SysAssert(this->_sharedItem->coordHolder->size.pcInt.w > 0 && this->_sharedItem->coordHolder->size.pcInt.h > 0);
985 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
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;
993 return this->_sharedItem->nativeBitmap->Construct(pcRect);
998 _BitmapImpl::Construct(const FloatDimension& vcDimF, BitmapPixelFormat pixelFormat)
1000 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1002 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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);
1006 switch (pixelFormat)
1008 case BITMAP_PIXEL_FORMAT_RGB565:
1009 case BITMAP_PIXEL_FORMAT_ARGB8888:
1010 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
1013 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
1018 _Util::Dimension<float> vcUtilDimF = { vcDimF.width, vcDimF.height };
1020 this->_sharedItem->coordHolder->ResetFromVc(vcUtilDimF);
1022 Dimension pcDim(this->_sharedItem->coordHolder->size.pcInt.w, this->_sharedItem->coordHolder->size.pcInt.h);
1024 return this->_sharedItem->nativeBitmap->Construct(pcDim, pixelFormat);
1029 _BitmapImpl::Construct(const _CanvasImpl& canvas, const FloatRectangle& vcRectF)
1031 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1033 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
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.");
1038 FloatRectangle rtCanvasF = canvas.GetBoundsF();
1040 SysTryReturnResult(NID_GRP, !rtCanvasF.IsEmpty(), E_INVALID_ARG, "A canvas is empty.");
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);
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);
1046 Tizen::Graphics::_Canvas* pCanvasEx = canvas._pNativeCanvas;
1049 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
1051 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
1053 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
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;
1061 return this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, pcRect);
1066 _BitmapImpl::Construct(const _BitmapImpl& bitmap, const FloatRectangle& vcRectF)
1068 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
1070 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
1072 SysTryReturnResult(NID_GRP, BITMAPIMPL_IS_VALID(&bitmap), E_INVALID_ARG, "The source bitmap is invalid.");
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);
1076 FloatRectangle rtBitmapF(0, 0, bitmap.GetWidthF(), bitmap.GetHeightF());
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);
1080 _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(bitmap);
1083 _Util::Dimension<float> vcDimF = { vcRectF.width, vcRectF.height };
1085 this->_sharedItem->coordHolder->ResetFromVc(vcDimF);
1087 FloatRectangle pcRectF = _ResUtil::ConvertToPhyCoord(vcRectF);
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;
1095 result r = E_SUCCESS;
1097 if (Tizen::Graphics::_IsLazyScalingBitmap(bitmap))
1099 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(bitmap);
1101 r = this->_sharedItem->nativeBitmap->Construct(*pSrcScaledBitmapEx, pcRect);
1105 r = this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, pcRect);
1113 _BitmapImpl::Scale(const Dimension& vc_dim)
1115 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
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);
1119 if (vc_dim.width == this->GetWidth() && vc_dim.height == this->GetHeight())
1125 return this->Scale(FloatDimension(float(vc_dim.width), float(vc_dim.height)));
1130 _BitmapImpl::Scale(const FloatDimension& vcDimF)
1132 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
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);
1136 if (vcDimF.width == this->GetWidthF() && vcDimF.height == this->GetHeightF())
1141 _UpdateBitmapTimeStamp(*this);
1143 result r = E_SUCCESS;
1145 _Util::AccumList<_Util::Pair<float, float> > scalingValue;
1147 _GetScaleInfo(this->GetScalingQuality(), this->GetWidthF(), this->GetHeightF(), vcDimF.width, vcDimF.height, scalingValue);
1149 for (_Util::AccumList<_Util::Pair<float, float> >::Iterator iter = scalingValue.End(); iter != scalingValue.Begin(); --iter)
1151 this->__Scale((iter-1)->first, (iter-1)->second);
1158 _BitmapImpl::Merge(const Point& vc_dest, const _BitmapImpl& src, const Rectangle& vc_srcRect)
1160 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1162 SysTryReturnResult(NID_GRP, &src && src._sharedItem.get(), E_INVALID_ARG, "The source bitmap is invalid.");
1164 SysTryReturnResult(NID_GRP, src._sharedItem->nativeBitmap->IsValid(), E_INVALID_ARG, "The source bitmap is invalid.");
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);
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);
1172 if ((vc_srcRect.width == 0) || (vc_srcRect.height == 0))
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);
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)));
1186 _BitmapImpl::Merge(const FloatPoint& destVcPosF, const _BitmapImpl& srcBitmap, const FloatRectangle& srcVcRectF)
1188 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1190 SysTryReturnResult(NID_GRP, &srcBitmap && srcBitmap._sharedItem.get(), E_INVALID_ARG, "The source bitmap is invalid.");
1192 SysTryReturnResult(NID_GRP, srcBitmap._sharedItem->nativeBitmap->IsValid(), E_INVALID_ARG, "The source bitmap is invalid.");
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);
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);
1200 if ((srcVcRectF.width == 0.0f) || (srcVcRectF.height == 0.0f))
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);
1208 _UpdateBitmapTimeStamp(*this);
1210 _Bitmap* pSrcBitmapEx = Tizen::Graphics::_GetBitmapEx(srcBitmap);
1211 _Bitmap* pDstBitmapEx = this->_sharedItem->nativeBitmap.get();
1213 Point destVcPos(_FloatToIntForPos(destVcPosF.x), _FloatToIntForPos(destVcPosF.y));
1214 Rectangle srcVcRect;
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);
1221 if (_ResUtil::NeedToConvertCoord())
1223 FloatPoint destPcPosF = _ResUtil::ConvertToPhyCoord(destVcPosF);
1224 FloatRectangle srcPcRectF = _ResUtil::ConvertToPhyCoord(srcVcRectF);
1226 Point destPcPos(_FloatToIntForPos(destPcPosF.x), _FloatToIntForPos(destPcPosF.y));
1227 Rectangle srcPcRect;
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);
1235 case 0: scaled bitmap -> scaled bitmap
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)
1246 int caseNo = (Tizen::Graphics::_IsLazyScalingBitmap(srcBitmap)) ? 2 : 0;
1247 caseNo += (Tizen::Graphics::_IsLazyScalingBitmap(*this)) ? 1 : 0;
1251 case 0: // source: pre-scale, destination: pre-scale --> merge by using the physical coordinate
1253 return pDstBitmapEx->Merge(destPcPos, *pSrcBitmapEx, srcPcRect);
1255 case 1: // source: pre-scale --> level0 bitmap: merge after enlarging, level1 bitmap: merge from source directly
1257 result r = E_SUCCESS;
1261 _Bitmap srcResizedBitmap;
1265 srcVcDim.width = static_cast<int>(srcBitmap._sharedItem->coordHolder->size.vcFloatActual.w);
1266 srcVcDim.height = static_cast<int>(srcBitmap._sharedItem->coordHolder->size.vcFloatActual.h);
1268 r = srcResizedBitmap.Construct(srcVcDim, pSrcBitmapEx->GetPixelColorFormat());
1270 SysTryReturnResult(NID_GRP, !IsFailed(r), E_OUT_OF_MEMORY, "Fails to allocate memory.");
1273 _UpdateScaledBitmapEx(pSrcBitmapEx, &srcResizedBitmap);
1275 r = pDstBitmapEx->Merge(destVcPos, srcResizedBitmap, srcVcRect);
1279 if (!IsFailed(r) && this->_sharedItem->scaledNativeBitmap.get())
1281 return this->_sharedItem->scaledNativeBitmap->Merge(destPcPos, *pSrcBitmapEx, srcPcRect);
1286 case 2: // destination: pre-scale --> merge from the level1 bitmap of source
1288 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(srcBitmap);
1290 SysTryReturnResult(NID_GRP, pSrcScaledBitmapEx != null, E_INVALID_ARG, "The source bitmap is invalid.");
1292 return pDstBitmapEx->Merge(destPcPos, *pSrcScaledBitmapEx, srcPcRect);
1294 case 3: // source: lazy-scale, destination: lazy-scale --> merge between level0, merge between level1
1296 result r = pDstBitmapEx->Merge(destVcPos, *pSrcBitmapEx, srcVcRect);
1298 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::_GetScaledBitmapEx(srcBitmap);
1300 if (this->_sharedItem->scaledNativeBitmap.get() && pSrcScaledBitmapEx)
1302 this->_sharedItem->scaledNativeBitmap->Merge(destPcPos, *pSrcScaledBitmapEx, srcPcRect);
1309 return E_INVALID_ARG;
1314 return pDstBitmapEx->Merge(destVcPos, *pSrcBitmapEx, srcVcRect);
1317 // for removing compiler warnings
1318 return E_OPERATION_FAILED;
1322 _BitmapImpl::GetHeight() const
1324 if (!(INSTANCE_IS_VALID))
1326 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1330 return this->_sharedItem->coordHolder->size.vcInt.h;
1334 _BitmapImpl::GetHeightF(void) const
1336 if (!(INSTANCE_IS_VALID))
1338 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1342 return this->_sharedItem->coordHolder->size.vcFloat.h;
1346 _BitmapImpl::GetActualHeight(void) const
1348 if (!(INSTANCE_IS_VALID))
1350 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1354 return this->_sharedItem->coordHolder->size.vcFloatActual.h;
1358 _BitmapImpl::GetWidth() const
1360 if (!(INSTANCE_IS_VALID))
1362 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1366 return this->_sharedItem->coordHolder->size.vcInt.w;
1370 _BitmapImpl::GetWidthF(void) const
1372 if (!(INSTANCE_IS_VALID))
1374 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1378 return this->_sharedItem->coordHolder->size.vcFloat.w;
1382 _BitmapImpl::GetActualWidth(void) const
1384 if (!(INSTANCE_IS_VALID))
1386 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1390 return this->_sharedItem->coordHolder->size.vcFloatActual.w;
1394 _BitmapImpl::GetBitsPerPixel() const
1396 if (!(INSTANCE_IS_VALID))
1398 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1402 return this->_sharedItem->nativeBitmap->GetBitsPerPixel();
1406 _BitmapImpl::GetPixelColorFormat() const
1408 if (!(INSTANCE_IS_VALID))
1410 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1411 return BITMAP_PIXEL_FORMAT_MAX;
1414 return this->_sharedItem->nativeBitmap->GetPixelColorFormat();
1418 _BitmapImpl::SetMaskingColor(const Color* pColor)
1420 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1422 _UpdateBitmapTimeStamp(*this);
1424 return this->_sharedItem->nativeBitmap->SetMaskingColor(pColor);
1428 _BitmapImpl::GetMaskingColor(Color& color) const
1430 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1432 return this->_sharedItem->nativeBitmap->GetMaskingColor(color);
1436 _BitmapImpl::SetAlphaConstant(int opacity)
1438 if (INSTANCE_IS_VALID)
1440 _UpdateBitmapTimeStamp(*this);
1442 this->_sharedItem->nativeBitmap->SetAlphaConstant(opacity);
1447 _BitmapImpl::GetAlphaConstant(void) const
1449 return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetAlphaConstant() : -1;
1453 _BitmapImpl::SetScalingQuality(BitmapScalingQuality quality)
1455 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1459 case BITMAP_SCALING_QUALITY_LOW:
1460 case BITMAP_SCALING_QUALITY_MID:
1461 case BITMAP_SCALING_QUALITY_HIGH:
1464 return E_INVALID_ARG;
1467 _UpdateBitmapTimeStamp(*this);
1469 this->_sharedItem->nativeBitmap->SetScalingQuality(quality);
1474 BitmapScalingQuality
1475 _BitmapImpl::GetScalingQuality(void) const
1477 return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetScalingQuality() : BITMAP_SCALING_QUALITY_LOW;
1481 _BitmapImpl::IsNinePatchedBitmap(void) const
1484 if (!(INSTANCE_IS_VALID))
1486 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1490 _Bitmap* pRefBitmap = (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get()) ? this->_sharedItem->scaledNativeBitmap.get() : this->_sharedItem->nativeBitmap.get();
1492 return pRefBitmap->IsNinePatchedBitmap();
1494 if (!(IS_INSTANCE_VALID))
1496 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1500 const Tizen::Base::String& associatedFileName = this->_sharedItem->associated.fileName;
1502 if (associatedFileName.IsEmpty())
1504 _Bitmap* pRefBitmap = (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get()) ? this->_sharedItem->scaledNativeBitmap.get() : this->_sharedItem->nativeBitmap.get();
1506 return pRefBitmap->IsNinePatchedBitmap();
1510 return HasNinePatchedBitmapTag(associatedFileName);
1516 _BitmapImpl::SetAsImmutable(void)
1518 if (INSTANCE_IS_VALID)
1520 if (this->_sharedItem->isMutable)
1524 if (this->Lock(bi) == E_SUCCESS)
1526 _Util::Pixmap dstImage(bi.width, bi.height, bi.bitsPerPixel, (void*)bi.pPixels, bi.pitch);
1527 dstImage.ConvertPremultiplied();
1532 this->_sharedItem->isMutable = false;
1533 this->_sharedItem->nativeBitmap->__isPremultiplied = true;
1535 //?? this->_sharedItem->scaledNativeBitmap
1541 _BitmapImpl::IsMutable(void) const
1543 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, false, "This instance is not constructed yet.");
1545 return this->_sharedItem->isMutable;
1549 _BitmapImpl::Lock(BufferInfo& info, long timeout)
1551 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1553 _UpdateBitmapTimeStamp(*this);
1555 return this->_sharedItem->nativeBitmap->Lock(info, timeout);
1559 _BitmapImpl::Unlock()
1561 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1563 result r = this->_sharedItem->nativeBitmap->Unlock();
1565 _UpdateBitmapTimeStamp(*this);
1567 if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1569 if (this->_sharedItem->scaledNativeBitmap.get())
1571 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1572 this->_sharedItem->scaledNativeBitmap->UpdateOpaqueInfo();
1580 _BitmapImpl::LockFast(BufferInfo& info, long timeout)
1582 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1584 _UpdateBitmapTimeStamp(*this);
1586 return this->_sharedItem->nativeBitmap->LockFast(info, timeout);
1590 _BitmapImpl::UnlockFast()
1592 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1594 result r = this->_sharedItem->nativeBitmap->UnlockFast();
1596 _UpdateBitmapTimeStamp(*this);
1598 if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1600 if (this->_sharedItem->scaledNativeBitmap.get())
1602 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1610 _BitmapImpl::CheckNinePatchedBitmapStrictly(const Bitmap& bitmap)
1612 const _BitmapImpl* pThis = _BitmapImpl::GetInstance(bitmap);
1614 if (!(IS_BITMAPIMPL_VALID(pThis)))
1616 SysLog(NID_GRP, "[E_OPERATION_FAILED] The given bitmap is not constructed yet.");
1620 if (pThis->_sharedItem->associated.hasBeenDetectedByUsingName)
1622 return pThis->_sharedItem->associated.determinedNinePatchedAtFirst;
1625 const Tizen::Base::String& associatedFileName = pThis->_sharedItem->associated.fileName;
1627 if (associatedFileName.IsEmpty())
1629 _Bitmap* pRefBitmap = (pThis->_sharedItem->lazyScaling && pThis->_sharedItem->scaledNativeBitmap.get()) ? pThis->_sharedItem->scaledNativeBitmap.get() : pThis->_sharedItem->nativeBitmap.get();
1631 return pRefBitmap->IsNinePatchedBitmap(true);
1635 bool ret = HasNinePatchedBitmapTag(associatedFileName);
1637 pThis->_sharedItem->associated.hasBeenDetectedByUsingName = true;
1638 pThis->_sharedItem->associated.determinedNinePatchedAtFirst = ret;
1645 _BitmapImpl::_SetCallback(void (* DestroyCallback)(void*), void* pDestroyCallbackParam,
1646 void (* LockCallback)(void*), void* pLockCallbackParam,
1647 void (* UnlockCallback)(void*), void* pUnlockCallbackParam)
1649 if (!(INSTANCE_IS_VALID))
1651 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1655 _UpdateBitmapTimeStamp(*this);
1657 this->_sharedItem->pDestroyCallbackFunc = DestroyCallback;
1658 this->_sharedItem->pDestroyCallbackParam = pDestroyCallbackParam;
1660 this->_sharedItem->pLockCallbackFunc = LockCallback;
1661 this->_sharedItem->pLockCallbackParam = pLockCallbackParam;
1663 this->_sharedItem->pUnlockCallbackFunc = UnlockCallback;
1664 this->_sharedItem->pUnlockCallbackParam = pUnlockCallbackParam;
1666 if (this->_sharedItem->nativeBitmap.get())
1668 this->_sharedItem->nativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam);
1671 if (this->_sharedItem->scaledNativeBitmap.get())
1673 this->_sharedItem->scaledNativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam);
1680 _BitmapImpl::GetExpandedBitmapN(const Bitmap& ninePatchedBitmap, int width, int height)
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);
1684 SysTryReturn(NID_GRP, &ninePatchedBitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1686 const _BitmapImpl* pSrcBitmapImpl = _BitmapImpl::GetInstance(ninePatchedBitmap);
1688 SysTryReturn(NID_GRP, BITMAPIMPL_IS_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1690 SysTryReturn(NID_GRP, pSrcBitmapImpl->IsNinePatchedBitmap(), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is not a nine-patched bitmap");
1692 BitmapPixelFormat pixelFormat = pSrcBitmapImpl->GetPixelColorFormat();
1694 switch (pixelFormat)
1696 case BITMAP_PIXEL_FORMAT_RGB565:
1697 case BITMAP_PIXEL_FORMAT_ARGB8888:
1700 SysTryReturn(NID_GRP, false, null, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] Pixel format of the given bitmap is invalid (%d)", pixelFormat);
1704 return _BitmapImpl::GetExpandedBitmapFN(ninePatchedBitmap, float(width), float (height));
1708 _BitmapImpl::GetExpandedBitmapFN(const Bitmap& ninePatchedBitmap, float width, float height)
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);
1712 SysTryReturn(NID_GRP, &ninePatchedBitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1714 const _BitmapImpl* pSrcBitmapImpl = _BitmapImpl::GetInstance(ninePatchedBitmap);
1716 SysTryReturn(NID_GRP, BITMAPIMPL_IS_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1718 SysTryReturn(NID_GRP, pSrcBitmapImpl->IsNinePatchedBitmap(), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is not a nine-patched bitmap");
1720 BitmapPixelFormat pixelFormat = pSrcBitmapImpl->GetPixelColorFormat();
1722 switch (pixelFormat)
1724 case BITMAP_PIXEL_FORMAT_RGB565:
1725 case BITMAP_PIXEL_FORMAT_ARGB8888:
1728 SysTryReturn(NID_GRP, false, null, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] Pixel format of the given bitmap is invalid (%d)", pixelFormat);
1732 std::auto_ptr<Bitmap> expandedBitmap(new (std::nothrow) Bitmap);
1734 SysTryReturn(NID_GRP, expandedBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1736 result r = expandedBitmap->Construct(FloatDimension(width, height), pixelFormat);
1738 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1740 _BitmapImpl* pDstBitmapImpl = _BitmapImpl::GetInstance(*expandedBitmap.get());
1742 SysAssert(pDstBitmapImpl != null);
1745 _Util::LockManager srcBitmap(*pSrcBitmapImpl);
1746 _Util::LockManager dstBitmap(*pDstBitmapImpl);
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());
1751 if (dstBitmap.GetBufferInfo().width < srcBitmap.GetBufferInfo().width - 2 ||
1752 dstBitmap.GetBufferInfo().height < srcBitmap.GetBufferInfo().height - 2)
1754 // down-scales from the source bitmap only
1755 const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1756 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1758 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1760 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1762 Rectangle sourRect(1, 1, srcBufferInfo.width - 2, srcBufferInfo.height - 2);
1763 Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
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);
1768 Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1772 const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1773 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1775 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1777 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1779 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
1781 Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
1783 // assert(pSrcBitmapImpl->_nativeBitmap);
1784 r = _Util::GetPatchList(boundsList, destRect, *pSrcBitmapImpl->_sharedItem->nativeBitmap.get());
1786 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] _Util::GetPatchList() failed (error = %#x)", r);
1788 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
1790 while (iter != boundsList.End())
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);
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);
1799 Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1807 return expandedBitmap.release();
1811 _BitmapImpl::GetColorReplacedBitmapN(const Bitmap& bitmap, const Color& replacedColor, const Color& newColor)
1813 SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1815 std::auto_ptr<Bitmap> pRetBitmap;
1818 Bitmap* pSrcBitmap = const_cast<Bitmap*>(&bitmap);
1821 pSrcBitmap->Lock(biSrc);
1823 pRetBitmap.reset(_BitmapUtil::CreateBitmapN(Dimension(biSrc.width, biSrc.height), biSrc.bitsPerPixel));
1825 if (pRetBitmap.get())
1828 pRetBitmap->Lock(biDst);
1830 if ((biSrc.pitch == biDst.pitch) && (biSrc.height == biDst.height))
1832 memcpy(biDst.pPixels, biSrc.pPixels, biDst.pitch * biDst.height);
1835 pRetBitmap->Unlock();
1838 pSrcBitmap->Unlock();
1840 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] New bitmap construction failed");
1843 BufferInfo bufferInfo;
1845 result r = pRetBitmap->Lock(bufferInfo);
1847 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap cannot retrieve the own buffer address");
1849 if (bufferInfo.bitsPerPixel == 32)
1851 typedef unsigned long Pixel;
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;
1858 Pixel keyAlpha = (newColor.GetRGB32() & 0xFF000000) >> 24;
1859 keyAlpha += (keyAlpha >> 7);
1863 for (int y = 0; y < bufferInfo.height; y++)
1865 for (int x = 0; x < bufferInfo.width; x++)
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;
1874 if ((*pBuffer & 0x00FFFFFF) == keyColor)
1876 Pixel alpha = (*pBuffer >> 8) & 0x00FF0000;
1877 alpha = (alpha * keyAlpha) & 0xFF000000;
1879 *pBuffer = alpha | chgColor;
1890 for (int y = 0; y < bufferInfo.height; y++)
1892 for (int x = 0; x < bufferInfo.width; x++)
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;
1901 if ((*pBuffer & 0x00FFFFFF) == keyColor)
1903 *pBuffer = (*pBuffer & 0xFF000000) | chgColor;
1913 else if (bufferInfo.bitsPerPixel == 16)
1915 typedef unsigned short Pixel;
1919 Pixel* pBuffer = reinterpret_cast<Pixel*>(bufferInfo.pPixels);
1920 int padding = bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel - bufferInfo.width;
1923 unsigned long color32 = replacedColor.GetRGB32();
1924 _Effect::Func::ConvertColorFormatFast(&keyColor, &color32);
1928 unsigned long color32 = newColor.GetRGB32() & 0x00FFFFFF;
1929 _Effect::Func::ConvertColorFormatFast(&chgColor, &color32);
1932 for (int y = 0; y < bufferInfo.height; y++)
1934 for (int x = 0; x < bufferInfo.width; x++)
1936 if (*pBuffer == keyColor)
1938 *pBuffer = chgColor;
1952 pRetBitmap->Unlock();
1954 return pRetBitmap.release();
1958 _BitmapImpl::CloneN(const Bitmap& bitmap)
1960 const _BitmapImpl* pSrcBitmapImpl = null;
1961 _BitmapImpl* pDstBitmapImpl = null;
1963 // source bitmap verification
1965 SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1967 pSrcBitmapImpl = _BitmapImpl::GetInstance(bitmap);
1969 SysTryReturn(NID_GRP, IS_BITMAPIMPL_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1972 // destination bitmap allocation
1973 std::auto_ptr<Bitmap> pRetBitmap(new (std::nothrow) Bitmap);
1976 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1978 pDstBitmapImpl = _BitmapImpl::GetInstance(*pRetBitmap.get());
1980 SysTryReturn(NID_GRP, pDstBitmapImpl && pDstBitmapImpl->_sharedItem.get() && !pDstBitmapImpl->_sharedItem->nativeBitmap->IsValid(), null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap is invalid");
1983 pDstBitmapImpl->_sharedItem = pSrcBitmapImpl->_sharedItem;
1985 return pRetBitmap.release();
1989 _BitmapImpl::GetNonScaledBitmapImplN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
1991 return _NonScale::CreateBitmapN(buffer, dim, pixelFormat);
1995 _BitmapImpl::GetNonScaledBitmapN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
1997 _BitmapImpl* pBitmapImpl = _BitmapImpl::GetNonScaledBitmapImplN(buffer, dim, pixelFormat);
1999 if (pBitmapImpl == null)
2004 return Tizen::Graphics::_BitmapUtil::CreateBitmapN(pBitmapImpl);
2008 _BitmapImpl::GetNonScaledBitmapN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat, const FloatDimension& logicalSize)
2010 Bitmap* pBitmap = GetNonScaledBitmapN(buffer, dim, pixelFormat);
2014 _BitmapImpl* pBitmapImpl = _BitmapImpl::GetInstance(*pBitmap);
2018 pBitmapImpl->_sharedItem->coordHolder->size.vcFloat.w = logicalSize.width;
2019 pBitmapImpl->_sharedItem->coordHolder->size.vcFloat.h = logicalSize.height;
2032 _BitmapImpl::HasNinePatchedBitmapTag(Tizen::Base::String fileName)
2034 const wchar_t* NINE_PATCHED_TAG = L".#.png"; // it must consist of lower-case characters
2035 const int NINE_PATCHED_TAG_LENGTH = 6;
2039 static wchar_t ToLower(wchar_t ch)
2041 return (ch >= L'A' && ch <= L'Z') ? ch + 'a' - 'A' : ch;
2045 _Util::String tempStr(fileName.GetPointer(), fileName.GetLength());
2047 while (tempStr.length > 0 && tempStr.pStart[tempStr.length - 1] == L' ')
2052 _Util::String testStr(tempStr.pStart, tempStr.length, tempStr.length - NINE_PATCHED_TAG_LENGTH, NINE_PATCHED_TAG_LENGTH);
2054 if (testStr.length == NINE_PATCHED_TAG_LENGTH)
2056 for (int i = 0; i < NINE_PATCHED_TAG_LENGTH; i++)
2058 if (Temp::ToLower(testStr.pStart[i]) == NINE_PATCHED_TAG[i])
2073 _BitmapImpl::SetAsPremultiplied(void)
2075 if (IS_INSTANCE_VALID)
2077 this->_sharedItem->isMutable = false;
2078 this->_sharedItem->nativeBitmap->__isPremultiplied = true;
2083 _BitmapImpl::SetAsNonpremultiplied(void)
2085 if (IS_INSTANCE_VALID)
2087 this->_sharedItem->isMutable = true;
2088 this->_sharedItem->nativeBitmap->__isPremultiplied = false;
2093 _BitmapImpl::ConvertToNonpremultiplied(Bitmap& bitmap, bool forceConversion)
2095 _BitmapImpl* pImpl = null;
2097 // bitmap verification
2099 SysTryReturn(NID_GRP, &bitmap, E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
2101 pImpl = _BitmapImpl::GetInstance(bitmap);
2103 SysTryReturn(NID_GRP, IS_BITMAPIMPL_VALID(pImpl), E_INVALID_ARG, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
2106 if (!forceConversion)
2108 SysTryReturn(NID_GRP, !pImpl->_sharedItem->isMutable, E_INVALID_CONDITION, E_INVALID_CONDITION, "[E_INVALID_CONDITION] The given bitmap is already non-premultipied");
2114 if (pImpl->Lock(bi) == E_SUCCESS)
2116 _Util::Pixmap dstImage(bi.width, bi.height, bi.bitsPerPixel, (void*)bi.pPixels, bi.pitch);
2117 dstImage.isPremultiplied = true;
2118 dstImage.ConvertNonpremultiplied();
2123 pImpl->_sharedItem->isMutable = true;
2124 pImpl->_sharedItem->nativeBitmap->__isPremultiplied = false;
2126 //?? this->_sharedItem->scaledNativeBitmap
2133 _BitmapImpl::_GetBitmapImpl(Bitmap* pBitmap)
2135 return pBitmap->__pImpl;
2139 _BitmapImpl::GetInstance(Bitmap& bitmap)
2141 return (&bitmap != null) ? bitmap.__pImpl : null;
2145 _BitmapImpl::GetInstance(const Bitmap& bitmap)
2147 return (&bitmap != null) ? bitmap.__pImpl : null;
2151 _BitmapImpl::__CheckValidity(bool canBufferExpand)
2153 if (this->_sharedItem.get())
2155 if (this->_sharedItem->nativeBitmap->IsValid())
2160 if (!this->_sharedItem->associated.fileName.IsEmpty())
2162 if (canBufferExpand)
2164 if (!__RealizeBuffer())
2166 // linkedFileName does not exist or is not a image file.
2167 this->Construct(Dimension(1, 1), BITMAP_PIXEL_FORMAT_ARGB8888);
2170 this->_sharedItem->associated.fileName.Clear();
2181 _BitmapImpl::__RealizeBuffer(void)
2184 int imageHeight = 0;
2186 Tizen::Media::MediaPixelFormat format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
2188 // The following does not consider the case of big-endian
2189 switch (this->_sharedItem->associated.pixelFormat)
2191 case BITMAP_PIXEL_FORMAT_RGB565:
2192 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGB565LE;
2194 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
2195 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGBA8888;
2197 case BITMAP_PIXEL_FORMAT_ARGB8888:
2199 format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
2203 std::auto_ptr<ByteBuffer> pImageBuffer(Tizen::Media::_ImageDecoder::DecodeToBufferN(this->_sharedItem->associated.fileName, format, imageWidth, imageHeight));
2205 if (pImageBuffer.get() == null)
2210 std::auto_ptr<_BitmapImpl> pTempBitmapImpl(_BitmapImpl::GetNonScaledBitmapImplN(*pImageBuffer, Dimension(imageWidth, imageHeight), this->_sharedItem->associated.pixelFormat));
2212 if (pTempBitmapImpl.get() == null || pTempBitmapImpl->_sharedItem.get() == null)
2217 pImageBuffer.reset();
2219 this->_sharedItem->Move(*(pTempBitmapImpl->_sharedItem.get()));
2225 _BitmapImpl::__Scale(const float width, const float height)
2227 result r = E_SUCCESS;
2229 _Util::Dimension<float> vcUtilDimF = { width, height };
2230 _BitmapCoordinateHolder tempCoordinateHolder;
2232 tempCoordinateHolder.ResetFromVc(vcUtilDimF);
2234 Dimension vcDim(tempCoordinateHolder.size.vcInt.w, tempCoordinateHolder.size.vcInt.h);
2236 if (_ResUtil::NeedToConvertCoord())
2238 if (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get())
2240 r = this->_sharedItem->nativeBitmap->Scale(vcDim);
2244 Dimension pcDim(tempCoordinateHolder.size.pcInt.w, tempCoordinateHolder.size.pcInt.h);
2246 r = this->_sharedItem->scaledNativeBitmap->Scale(pcDim);
2250 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
2252 // @ykahn If it fails, then how to undo its status.
2257 Dimension pcDim(tempCoordinateHolder.size.pcInt.w, tempCoordinateHolder.size.pcInt.h);
2259 r = this->_sharedItem->nativeBitmap->Scale(pcDim);
2264 r = this->_sharedItem->nativeBitmap->Scale(vcDim);
2269 memcpy(this->_sharedItem->coordHolder.get(), &tempCoordinateHolder, sizeof(tempCoordinateHolder));
2275 void _BitmapImpl::_SharedItem::Move(_BitmapImpl::_SharedItem& source)
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);
2284 }} // Tizen::Graphics