2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
5 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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())
49 #define BITMAPIMPL_IS_VALID(pBitmapImpl) (pBitmapImpl && const_cast<_BitmapImpl*>(pBitmapImpl)->__CheckValidity(true))
50 #define IS_BITMAPIMPL_VALID(pBitmapImpl) (pBitmapImpl && const_cast<_BitmapImpl*>(pBitmapImpl)->__CheckValidity(false))
57 _CheckValidityOfRectangle(const Tizen::Graphics::Rectangle& rect)
59 return ((rect.width > 0) && (rect.height > 0));
63 _CheckValidity(const Tizen::Graphics::Rectangle& rtSrc, const Tizen::Graphics::Rectangle& rtDest)
65 // check 1. is width/height less or equal than 0?
66 if (rtSrc.width <= 0 || rtSrc.height <= 0 || rtDest.width <= 0 || rtDest.height <= 0)
68 return false; // "[E_OUT_OF_RANGE] The argument is out of range. (src(w:%d,h:%d), dst(w:%d,h:%d))", rtSrc.width, rtSrc.height, rtDest.width, rtDest.height);
71 // check 2. is src exiting outside of dest entirely?
72 if (rtSrc.x > rtDest.x + rtDest.width - 1 || rtSrc.x + rtSrc.width - 1 < rtDest.x)
74 return false; // "[E_OUT_OF_RANGE] The argument is out of range. (src(x:%d,y:%d,w:%d,h:%d), dst(x:%d,y:%d,w:%d,h:%d))", rtSrc.x, rtSrc.y, rtSrc.width, rtSrc.height, rtDest.x, rtDest.y, rtDest.width, rtDest.height);
77 if (rtSrc.y > rtDest.y + rtDest.height - 1 || rtSrc.y + rtSrc.height - 1 < rtDest.y)
79 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);
86 _GetBytesPerPixel(Tizen::Graphics::BitmapPixelFormat pixelFormat)
88 if (pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565)
92 else if (pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888 || pixelFormat == Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8)
103 _CheckBufferSize(const Tizen::Base::ByteBuffer& buffer, const Tizen::Graphics::Dimension& dim, Tizen::Graphics::BitmapPixelFormat pixelFormat)
105 int bytePerPixel = _GetBytesPerPixel(pixelFormat);
107 if (bytePerPixel == 0)
109 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
112 int byteNum = buffer.GetLimit();
113 int expectedBufferSize = dim.width * dim.height * bytePerPixel;
115 SysTryReturnResult(NID_GRP, expectedBufferSize <= byteNum, E_INVALID_ARG, "A buffer size is not correct. (expected: %d, actual: %d)", expectedBufferSize, byteNum);
121 _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)
125 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565:
127 Tizen::Graphics::_Util::Pixmap dstImage(destSize.width, destSize.height, 16, (void*) destBuffer.GetPointer());
128 Tizen::Graphics::_Util::Pixmap srcImage(sourSize.width, sourSize.height, 16, (void*) sourBuffer.GetPointer());
129 return Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, destSize.width, destSize.height, srcImage);
131 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888:
133 Tizen::Graphics::_Util::Pixmap dstImage(destSize.width, destSize.height, 32, (void*) destBuffer.GetPointer());
134 Tizen::Graphics::_Util::Pixmap srcImage(sourSize.width, sourSize.height, 32, (void*) sourBuffer.GetPointer());
135 return Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, destSize.width, destSize.height, srcImage);
137 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8:
145 _UpdateScaledBitmapEx(Tizen::Graphics::_Bitmap* pSrcBitmap, Tizen::Graphics::_Bitmap* pDstBitmap)
147 if (!(pSrcBitmap && pDstBitmap && pSrcBitmap->GetPixelColorFormat() == pDstBitmap->GetPixelColorFormat()))
152 Tizen::Graphics::BufferInfo srcBufferInfo;
153 Tizen::Graphics::BufferInfo dstBufferInfo;
156 if (pSrcBitmap->Lock(srcBufferInfo) != E_SUCCESS)
161 result r = pDstBitmap->Lock(dstBufferInfo);
164 pSrcBitmap->Unlock();
173 switch (pSrcBitmap->GetPixelColorFormat())
175 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_RGB565:
177 Tizen::Graphics::_Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, 16, (void*) dstBufferInfo.pPixels);
178 Tizen::Graphics::_Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, 16, (void*) srcBufferInfo.pPixels);
179 ret = Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, dstBufferInfo.width, dstBufferInfo.height, srcImage);
183 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_ARGB8888:
185 Tizen::Graphics::_Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, 32, (void*) dstBufferInfo.pPixels);
186 Tizen::Graphics::_Util::Pixmap srcImage(srcBufferInfo.width, srcBufferInfo.height, 32, (void*) srcBufferInfo.pPixels);
187 ret = Tizen::Graphics::_Effect::ScaleImage(dstImage, 0, 0, dstBufferInfo.width, dstBufferInfo.height, srcImage);
191 case Tizen::Graphics::BITMAP_PIXEL_FORMAT_R8G8B8A8:
198 pSrcBitmap->Unlock();
199 pDstBitmap->Unlock();
204 ////////////////////////////////////////////////////////////////////////////////
207 _UpdateBitmapTimeStampInternal(void)
209 static unsigned long staticTimeStamp = 0;
213 staticTimeStamp = (staticTimeStamp == 0) ? (staticTimeStamp + 1) : staticTimeStamp;
215 return staticTimeStamp;
220 ////////////////////////////////////////////////////////////////////////////////
222 namespace Tizen { namespace Graphics
226 _GetBitmapTimeStamp(const Tizen::Graphics::_BitmapImpl& bitmap)
228 Tizen::Graphics::_Bitmap* _nativeBitmap = Tizen::Graphics::GetBitmapEx(bitmap);
230 return (_nativeBitmap) ? _nativeBitmap->GetTimeStamp() : 0;
234 _UpdateBitmapTimeStamp(Tizen::Graphics::_BitmapImpl& bitmap)
236 Tizen::Graphics::_Bitmap* _nativeBitmap = Tizen::Graphics::GetBitmapEx(bitmap);
240 _nativeBitmap->SetTimeStamp(_UpdateBitmapTimeStampInternal());
241 return _nativeBitmap->GetTimeStamp();
247 ////////////////////////////////////////////////////////////////////////////////
249 _BitmapImpl::_BitmapImpl(void)
250 : _sharedItem(std::tr1::shared_ptr<_SharedItem>(new (std::nothrow)_SharedItem))
252 if (this->_sharedItem.get())
254 this->_sharedItem->nativeBitmap.reset(new (std::nothrow) _Bitmap);
255 this->_sharedItem->coordHolder.reset(new (std::nothrow) _BitmapCoordHolder);
256 this->_sharedItem->lazyScaling = 0;
257 this->_sharedItem->scaledNativeBitmap.reset(null);
258 this->_sharedItem->pDestroyCallbackFunc = null;
259 this->_sharedItem->pDestroyCallbackParam = null;
260 this->_sharedItem->pLockCallbackFunc = null;
261 this->_sharedItem->pLockCallbackParam = null;
262 this->_sharedItem->pUnlockCallbackFunc = null;
263 this->_sharedItem->pUnlockCallbackParam = null;
264 this->_sharedItem->isMutable = true;
265 this->_sharedItem->associated.pixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
267 if (this->_sharedItem->nativeBitmap.get() == null || this->_sharedItem->coordHolder.get() == null)
269 this->_sharedItem->nativeBitmap.reset();
270 this->_sharedItem->coordHolder.reset();
271 this->_sharedItem.reset();
277 _UpdateBitmapTimeStamp(*this);
280 _BitmapImpl::~_BitmapImpl(void)
282 if (this->_sharedItem.get())
284 if (this->_sharedItem->pDestroyCallbackFunc)
286 if (this->_sharedItem.unique())
288 this->_sharedItem->pDestroyCallbackFunc(this->_sharedItem->pDestroyCallbackParam);
295 _BitmapImpl::IsConstructed(void) const
297 return (this->_sharedItem.get() && (this->_sharedItem->nativeBitmap->IsValid() || !this->_sharedItem->associated.fileName.IsEmpty()));
301 _BitmapImpl::Construct(const Rectangle& vc_rect)
303 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
305 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
307 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);
309 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);
311 if (_ResUtil::NeedToConvertCoord())
313 Rectangle pc_rect = _ResUtil::ConvertToPhyCoord(vc_rect);
316 pc_rect.width = (pc_rect.width > 0) ? pc_rect.width : 1;
317 pc_rect.height = (pc_rect.height > 0) ? pc_rect.height : 1;
319 result r = this->_sharedItem->nativeBitmap->Construct(pc_rect);
323 this->_sharedItem->coordHolder->Init(vc_rect);
324 this->_sharedItem->coordHolder->bitmapSize.phyCoord.w = pc_rect.width;
325 this->_sharedItem->coordHolder->bitmapSize.phyCoord.h = pc_rect.height;
332 return this->_sharedItem->nativeBitmap->Construct(vc_rect);
337 _BitmapImpl::Construct(const Dimension& vc_dim, BitmapPixelFormat pixelFormat)
339 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
341 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
344 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);
346 int size = vc_dim.width * vc_dim.height;
350 case BITMAP_PIXEL_FORMAT_RGB565:
351 size *= sizeof(unsigned short);
353 case BITMAP_PIXEL_FORMAT_ARGB8888:
354 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
355 size *= sizeof(unsigned long);
358 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
362 if (_ResUtil::NeedToConvertCoord())
364 Dimension pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
367 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
368 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
370 result r = this->_sharedItem->nativeBitmap->Construct(pc_dim, pixelFormat);
374 _ResUtil::Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
376 this->_sharedItem->coordHolder->Init(vc_rect);
377 this->_sharedItem->coordHolder->bitmapSize.phyCoord.w = pc_dim.width;
378 this->_sharedItem->coordHolder->bitmapSize.phyCoord.h = pc_dim.height;
385 return this->_sharedItem->nativeBitmap->Construct(vc_dim, pixelFormat);
390 _BitmapImpl::Construct(const _CanvasImpl& canvas, const Rectangle& vc_rect)
392 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
394 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
396 SysTryReturnResult(NID_GRP, &canvas, E_INVALID_ARG, "A canvas is invalid.");
397 SysTryReturnResult(NID_GRP, canvas._pNativeCanvas && canvas._pNativeCanvas->IsValid(), E_INVALID_ARG, "A canvas is invalid.");
399 Rectangle rtCanvas = canvas.GetBounds();
401 SysTryReturnResult(NID_GRP, !rtCanvas.IsEmpty(), E_INVALID_ARG, "A canvas is empty.");
403 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);
405 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);
407 Tizen::Graphics::_Canvas* pCanvasEx = canvas._pNativeCanvas;
409 if (_ResUtil::NeedToConvertCoord())
411 Rectangle pc_rect = _ResUtil::ConvertToPhyCoord(vc_rect);
413 // special case (kiniirana)
414 pc_rect.width = (pc_rect.width > 0) ? pc_rect.width : 1;
415 pc_rect.height = (pc_rect.height > 0) ? pc_rect.height : 1;
417 result r = this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, pc_rect);
421 this->_sharedItem->coordHolder->Init(vc_rect);
428 return this->_sharedItem->nativeBitmap->Construct(*pCanvasEx, vc_rect);
433 _BitmapImpl::Construct(const _BitmapImpl& bitmap, const Rectangle& vc_rect)
435 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
437 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
439 SysTryReturnResult(NID_GRP, BITMAPIMPL_IS_VALID(&bitmap), E_INVALID_ARG, "The source bitmap is invalid.");
441 Rectangle rtBitmap(0, 0, bitmap.GetWidth(), bitmap.GetHeight());
443 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);
445 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);
447 _Bitmap* pSrcBitmapEx = Tizen::Graphics::GetBitmapEx(bitmap);
449 if (_ResUtil::NeedToConvertCoord())
451 result r = E_SUCCESS;
452 Rectangle pc_rect = _ResUtil::ConvertToPhyCoord(vc_rect);
455 pc_rect.width = (pc_rect.width > 0) ? pc_rect.width : 1;
456 pc_rect.height = (pc_rect.height > 0) ? pc_rect.height : 1;
458 if (Tizen::Graphics::IsLazyScalingBitmap(bitmap))
460 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::GetScaledBitmapEx(bitmap);
462 r = this->_sharedItem->nativeBitmap->Construct(*pSrcScaledBitmapEx, pc_rect);
466 r = this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, pc_rect);
471 this->_sharedItem->coordHolder->Init(vc_rect);
478 return this->_sharedItem->nativeBitmap->Construct(*pSrcBitmapEx, vc_rect);
483 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat)
486 return this->Construct(buffer, rq_dim, pixelFormat, true);
488 // return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_AUTO);
489 // return this->Construct(buffer, rq_dim, pixelFormat, BUFFER_SCALING_NONE);
491 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
493 SysTryReturnResult(NID_GRP, __pImpl && this->_nativeBitmap, E_OUT_OF_MEMORY, "Fails to allocate memory.");
495 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);
497 SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
500 // buffer size should be verified.
501 int bytePerPixel = 0;
502 if (BITMAP_PIXEL_FORMAT_RGB565 == pixelFormat)
506 else if (BITMAP_PIXEL_FORMAT_ARGB8888 == pixelFormat || BITMAP_PIXEL_FORMAT_R8G8B8A8 == pixelFormat)
512 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
515 int byteNum = buffer.GetLimit();
516 int expectedBufferSize = rq_dim.width * rq_dim.height * bytePerPixel;
518 SysTryReturnResult(NID_GRP, expectedBufferSize <= byteNum, E_INVALID_ARG, "A buffer size is not correct.");
521 if (_ResUtil::NeedToConvertCoord())
527 pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
530 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
531 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
533 if (pc_dim.width * 2 == rq_dim.width && pc_dim.height * 2 == rq_dim.height)
535 int pitch = rq_dim.width;
537 if (pixelFormat == BITMAP_PIXEL_FORMAT_ARGB8888)
539 const unsigned long MASK = 0x00FF00FF;
541 unsigned long* pBuffer = (unsigned long*) buffer.GetPointer();
542 for (int y = 0; y < pc_dim.height; y++)
544 for (int x = 0; x < pc_dim.width; x++)
546 unsigned long add1 = (pBuffer[0] & MASK) + (pBuffer[1] & MASK) + (pBuffer[pitch] & MASK) + (pBuffer[pitch + 1] & MASK);
547 unsigned long add2 = ((pBuffer[0] >> 8) & MASK) + ((pBuffer[1] >> 8) & MASK) + ((pBuffer[pitch] >> 8) & MASK) + ((pBuffer[pitch + 1] >> 8) & MASK);
549 unsigned long pix = ((add1 >> 2) & MASK) | (((add2 >> 2) & MASK) << 8);
553 pBuffer[pitch] = pix;
554 pBuffer[pitch + 1] = pix;
561 else if (pixelFormat == BITMAP_PIXEL_FORMAT_RGB565)
563 const unsigned short MASK1 = 0xF81F;
564 const unsigned short MASK2 = 0x07E0;
565 const unsigned short CHROMAKEY = 0xF81F | 0x0020;
569 unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
570 unsigned short* pBufferEnd = pBuffer + rq_dim.width * rq_dim.height;
572 while (pBuffer < pBufferEnd)
574 if (*pBuffer == CHROMAKEY)
582 hasChromakey = (pBuffer < pBufferEnd);
587 ; // pass through default scaling algorithm
591 unsigned short* pBuffer = (unsigned short*) buffer.GetPointer();
593 for (int y = 0; y < pc_dim.height; y++)
595 for (int x = 0; x < pc_dim.width; x++)
597 unsigned long add1 = (unsigned long) (pBuffer[0] & MASK1) + (unsigned long) (pBuffer[1] & MASK1) + (unsigned long) (pBuffer[pitch] & MASK1) + (unsigned long) (pBuffer[pitch + 1] & MASK1);
598 unsigned long add2 = (pBuffer[0] & MASK2) + (pBuffer[1] & MASK2) + (pBuffer[pitch] & MASK2) + (pBuffer[pitch + 1] & MASK2);
600 unsigned long pix = ((add1 >> 2) & MASK1) | ((add2 >> 2) & MASK2);
604 pBuffer[pitch] = pix;
605 pBuffer[pitch + 1] = pix;
615 result r = this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
619 this->_nativeBitmap->Scale(pc_dim);
621 Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
622 Rect pc_rect(0, 0, pc_dim.width, pc_dim.height);
624 this->_coordHolder->bitmapSize.required = vc_rect;
625 this->_coordHolder->bitmapSize.phyCoord = pc_rect;
626 this->_coordHolder->bitmapSize.virCoord = vc_rect;
633 return this->_nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
640 _BitmapImpl::Construct(const BufferInfo& bufferInfo)
642 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
644 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
646 SysTryReturnResult(NID_GRP, (bufferInfo.width > 0) && (bufferInfo.height > 0) && (bufferInfo.pitch > 0)
648 , "Invalid argument (BufferInfo::width = %d, BufferInfo::height = %d, BufferInfo::pitch = %d)"
649 , bufferInfo.width, bufferInfo.height, bufferInfo.pitch);
651 SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel > 0
653 , "Invalid argument (BufferInfo::bitsPerPixel = %d)"
654 , bufferInfo.bitsPerPixel);
656 SysTryReturnResult(NID_GRP, (bufferInfo.pixelFormat > PIXEL_FORMAT_MIN) && (bufferInfo.pixelFormat < PIXEL_FORMAT_MAX)
658 , "Invalid argument (BufferInfo::pixelFormat = %d)"
659 , bufferInfo.pixelFormat);
661 SysTryReturnResult(NID_GRP, bufferInfo.pPixels != null
663 , "Invalid argument (BufferInfo::pPixels = null)");
665 SysTryReturnResult(NID_GRP, bufferInfo.bitsPerPixel == 32 || bufferInfo.bitsPerPixel == 16
666 , E_UNSUPPORTED_FORMAT
667 , "Unsupported format (BufferInfo::bitsPerPixel = %d)"
668 , bufferInfo.bitsPerPixel);
670 BitmapPixelFormat bitmapPixelFormat = BITMAP_PIXEL_FORMAT_MIN;
672 switch (bufferInfo.pixelFormat)
674 case PIXEL_FORMAT_RGB565:
675 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_RGB565;
677 case PIXEL_FORMAT_ARGB8888:
678 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_ARGB8888;
680 case PIXEL_FORMAT_R8G8B8A8:
681 bitmapPixelFormat = BITMAP_PIXEL_FORMAT_R8G8B8A8;
687 SysTryReturnResult(NID_GRP, bitmapPixelFormat != BITMAP_PIXEL_FORMAT_MIN
688 , E_UNSUPPORTED_FORMAT
689 , "Unsupported format (BufferInfo::pixelFormat = %d)"
690 , bufferInfo.pixelFormat);
692 result r = this->Construct(static_cast<const byte*>(bufferInfo.pPixels), bufferInfo.pitch * bufferInfo.height, Dimension(bufferInfo.width, bufferInfo.height), bitmapPixelFormat, false);
694 SysTryReturn(NID_GRP, r == E_SUCCESS, r, r, "[%s] Propagating.", GetErrorMessage(r));
696 this->_sharedItem->nativeBitmap->_SetOwnership(false);
702 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
704 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
706 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
708 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);
710 SysTryReturnResult(NID_GRP, BITMAP_PIXEL_FORMAT_MIN < pixelFormat && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
712 result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
719 if (_ResUtil::NeedToConvertCoord())
721 result r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
731 pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
734 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
735 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
737 const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
739 this->_sharedItem->nativeBitmap->ScaleEx(pc_dim, quality);
744 vc_dim = _ResUtil::ConvertToVirCoord(pc_dim);
747 _ResUtil::Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
748 _ResUtil::Rect pc_rect(0, 0, pc_dim.width, pc_dim.height);
750 this->_sharedItem->coordHolder->bitmapSize.required = vc_rect;
751 this->_sharedItem->coordHolder->bitmapSize.phyCoord = pc_rect;
752 this->_sharedItem->coordHolder->bitmapSize.virCoord = vc_rect;
759 return this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
764 _BitmapImpl::Construct(const byte* pBuffer, int bufSize, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, bool autoScaling)
766 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
768 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
770 SysTryReturnResult(NID_GRP, pBuffer, E_INVALID_ARG, "The specified buffer pointer is invalid.", rq_dim.width, rq_dim.height);
772 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);
774 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
776 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);
778 if (_ResUtil::NeedToConvertCoord())
780 result r = this->_sharedItem->nativeBitmap->Construct(pBuffer, bufSize, rq_dim, pixelFormat);
790 pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
793 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
794 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
796 const BitmapScalingQuality quality = BITMAP_SCALING_QUALITY_LOW;
798 this->_sharedItem->nativeBitmap->ScaleEx(pc_dim, quality);
803 vc_dim = _ResUtil::ConvertToVirCoord(pc_dim);
806 _ResUtil::Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
807 _ResUtil::Rect pc_rect(0, 0, pc_dim.width, pc_dim.height);
809 this->_sharedItem->coordHolder->bitmapSize.required = vc_rect;
810 this->_sharedItem->coordHolder->bitmapSize.phyCoord = pc_rect;
811 this->_sharedItem->coordHolder->bitmapSize.virCoord = vc_rect;
818 return this->_sharedItem->nativeBitmap->Construct(pBuffer, bufSize, rq_dim, pixelFormat);
823 _BitmapImpl::Construct(const Tizen::Base::ByteBuffer& buffer, const Dimension& rq_dim, BitmapPixelFormat pixelFormat, BufferScaling bufferScaling)
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, 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);
831 SysTryReturnResult(NID_GRP, pixelFormat > BITMAP_PIXEL_FORMAT_MIN && pixelFormat < BITMAP_PIXEL_FORMAT_MAX, E_INVALID_ARG, "BitmapPixelFormat(%d) is the invalid argument.", pixelFormat);
833 result r = _CheckBufferSize(buffer, rq_dim, pixelFormat);
840 switch (bufferScaling)
842 case BUFFER_SCALING_AUTO:
843 return this->Construct(buffer, rq_dim, pixelFormat, true);
844 case BUFFER_SCALING_NONE:
847 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "BufferScaling(%d) is the invalid argument.", pixelFormat);
851 if (_ResUtil::NeedToConvertCoord())
853 result r = this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
857 Dimension vc_dim = rq_dim;
858 Dimension pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
861 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
862 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
864 this->_sharedItem->lazyScaling = 1;
866 _ResUtil::Rect vc_rect(0, 0, vc_dim.width, vc_dim.height);
867 _ResUtil::Rect pc_rect(0, 0, pc_dim.width, pc_dim.height);
869 this->_sharedItem->coordHolder->bitmapSize.required = vc_rect;
870 this->_sharedItem->coordHolder->bitmapSize.phyCoord = pc_rect;
871 this->_sharedItem->coordHolder->bitmapSize.virCoord = vc_rect;
874 bool isScaledBufferAvailable = false;
876 Tizen::Base::ByteBuffer scaledBuffer;
879 int scaledCapacity = _GetBytesPerPixel(pixelFormat) * (pc_dim.width * pc_dim.height);
880 SysAssert(scaledCapacity > 0);
883 isScaledBufferAvailable = (scaledBuffer.Construct(scaledCapacity) == E_SUCCESS);
886 if (isScaledBufferAvailable)
888 _ScaleBuffer(scaledBuffer, pc_dim, buffer, vc_dim, pixelFormat);
890 this->_sharedItem->scaledNativeBitmap.reset(new (std::nothrow) _Bitmap);
892 if (this->_sharedItem->scaledNativeBitmap.get())
894 if (this->_sharedItem->scaledNativeBitmap->Construct(scaledBuffer, pc_dim, pixelFormat) == E_SUCCESS)
898 // BufferInfo bufferInfo;
899 // this->_scaledNativeBitmap->Lock(bufferInfo);
900 // this->_scaledNativeBitmap->Unlock();
905 this->_sharedItem->scaledNativeBitmap.reset(null);
916 return this->_sharedItem->nativeBitmap->Construct(buffer, rq_dim, pixelFormat);
921 _BitmapImpl::Construct(const Tizen::Base::String& fileName, BitmapPixelFormat pixelFormat)
923 SysTryReturnResult(NID_GRP, this, E_OUT_OF_MEMORY, "This instance is not allocated yet.");
925 SysTryReturnResult(NID_GRP, this->_sharedItem.get(), E_OUT_OF_MEMORY, "Fails to allocate memory.");
929 case BITMAP_PIXEL_FORMAT_RGB565:
930 case BITMAP_PIXEL_FORMAT_ARGB8888:
931 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
934 SysTryReturnResult(NID_GRP, false, E_INVALID_ARG, "BitmapPixelFormat(%d) is invalid argument.", pixelFormat);
938 SysTryReturnResult(NID_GRP, Tizen::Io::File::IsFileExist(fileName), E_INVALID_ARG, "The specified file is not found.");
940 // This function doesn't verify the specified image file.
941 this->_sharedItem->associated.fileName = fileName;
942 this->_sharedItem->associated.pixelFormat = pixelFormat;
947 const Tizen::Base::String&
948 _BitmapImpl::GetFileName(void) const
950 if (this && this->_sharedItem.get())
952 return this->_sharedItem->associated.fileName;
956 static Tizen::Base::String emptyString;
964 _BitmapImpl::Scale(const Dimension& vc_dim)
966 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
968 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);
970 if (vc_dim.width == this->GetWidth() && vc_dim.height == this->GetHeight())
975 _UpdateBitmapTimeStamp(*this);
977 if (_ResUtil::NeedToConvertCoord())
979 if (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get())
981 Dimension pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
984 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
985 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
987 result r = this->_sharedItem->nativeBitmap->Scale(vc_dim);
991 Rectangle vc_rect(0, 0, vc_dim.width, vc_dim.height);
993 this->_sharedItem->coordHolder->Init(vc_rect);
994 this->_sharedItem->coordHolder->bitmapSize.phyCoord.w = pc_dim.width;
995 this->_sharedItem->coordHolder->bitmapSize.phyCoord.h = pc_dim.height;
997 result r = this->_sharedItem->scaledNativeBitmap->Scale(pc_dim);
1001 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1009 Dimension pc_dim = _ResUtil::ConvertToPhyCoord(vc_dim);
1012 pc_dim.width = (pc_dim.width > 0) ? pc_dim.width : 1;
1013 pc_dim.height = (pc_dim.height > 0) ? pc_dim.height : 1;
1015 result r = this->_sharedItem->nativeBitmap->Scale(pc_dim);
1019 Rectangle vc_rect(0, 0, vc_dim.width, vc_dim.height);
1021 this->_sharedItem->coordHolder->Init(vc_rect);
1022 this->_sharedItem->coordHolder->bitmapSize.phyCoord.w = pc_dim.width;
1023 this->_sharedItem->coordHolder->bitmapSize.phyCoord.h = pc_dim.height;
1031 return this->_sharedItem->nativeBitmap->Scale(vc_dim);
1036 _BitmapImpl::Merge(const Point& vc_dest, const _BitmapImpl& src, const Rectangle& vc_srcRect)
1038 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1040 SysTryReturnResult(NID_GRP, &src && src._sharedItem.get(), E_INVALID_ARG, "The source bitmap is invalid.");
1042 SysTryReturnResult(NID_GRP, src._sharedItem->nativeBitmap->IsValid(), E_INVALID_ARG, "The source bitmap is invalid.");
1044 SysTryReturnResult(NID_GRP, &vc_srcRect, E_INVALID_ARG, "The source rectangle is invalid.");
1045 SysTryReturnResult(NID_GRP, &vc_dest, E_INVALID_ARG, "The destination position is invalid.");
1046 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);
1048 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);
1050 if ((vc_srcRect.width == 0) || (vc_srcRect.height == 0))
1055 _UpdateBitmapTimeStamp(*this);
1057 Rectangle rtBitmap(0, 0, src.GetWidth(), src.GetHeight());
1058 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);
1060 _Bitmap* pSrcBitmapEx = Tizen::Graphics::GetBitmapEx(src);
1061 _Bitmap* pDstBitmapEx = this->_sharedItem->nativeBitmap.get();
1063 if (_ResUtil::NeedToConvertCoord())
1065 Point pc_dest = _ResUtil::ConvertToPhyCoord(vc_dest);
1066 Rectangle pc_srcRect = _ResUtil::ConvertToPhyCoord(vc_srcRect);
1069 case 0: scaled bitmap -> scaled bitmap
1071 case 1: scaled bitmap -> lazy scaled bitmap
1072 merge level 0 from the scaled source bitmap
1073 merge level 0(src) and level 1(dst)
1074 case 2: lazy scaled bitmap -> scaled bitmap
1075 merge level 1(src) and level 0(dst)
1076 case 3: lazy scaled bitmap -> lazy scaled bitmap
1077 merge level 0 (using virtual coordinate)
1078 merge level 1 (using physical coordinate)
1080 int caseNo = (Tizen::Graphics::IsLazyScalingBitmap(src)) ? 2 : 0;
1081 caseNo += (Tizen::Graphics::IsLazyScalingBitmap(*this)) ? 1 : 0;
1085 case 0: // source: pre-scale, destination: pre-scale --> merge by using the physical coordinate
1087 return pDstBitmapEx->Merge(pc_dest, *pSrcBitmapEx, pc_srcRect);
1089 case 1: // source: pre-scale --> level0 bitmap: merge after enlarging, level1 bitmap: merge from source directly
1091 result r = E_SUCCESS;
1095 _Bitmap srcResizedBitmap;
1097 Dimension srcVirDim(src._sharedItem->coordHolder->bitmapSize.virCoord.w, src._sharedItem->coordHolder->bitmapSize.virCoord.h);
1099 r = srcResizedBitmap.Construct(srcVirDim, pSrcBitmapEx->GetPixelColorFormat());
1100 SysTryReturnResult(NID_GRP, !IsFailed(r), E_OUT_OF_MEMORY, "Fails to allocate memory.");
1103 _UpdateScaledBitmapEx(pSrcBitmapEx, &srcResizedBitmap);
1105 r = pDstBitmapEx->Merge(vc_dest, srcResizedBitmap, vc_srcRect);
1109 if (!IsFailed(r) && this->_sharedItem->scaledNativeBitmap.get())
1111 return this->_sharedItem->scaledNativeBitmap->Merge(pc_dest, *pSrcBitmapEx, pc_srcRect);
1116 case 2: // destination: pre-scale --> merge from the level1 bitmap of source
1118 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::GetScaledBitmapEx(src);
1121 if (pSrcScaledBitmapEx)
1123 return pDstBitmapEx->Merge(pc_dest, *pSrcScaledBitmapEx, pc_srcRect);
1127 SysTryReturnResult(NID_GRP, 0, E_INVALID_ARG, "The source bitmap is invalid.");
1130 return E_INVALID_ARG;
1132 case 3: // source: lazy-scale, destination: lazy-scale --> merge between level0, merge between level1
1134 result r = pDstBitmapEx->Merge(vc_dest, *pSrcBitmapEx, vc_srcRect);
1136 _Bitmap* pSrcScaledBitmapEx = Tizen::Graphics::GetScaledBitmapEx(src);
1138 if (this->_sharedItem->scaledNativeBitmap.get() && pSrcScaledBitmapEx)
1140 this->_sharedItem->scaledNativeBitmap->Merge(pc_dest, *pSrcScaledBitmapEx, pc_srcRect);
1147 return E_INVALID_ARG;
1152 return pDstBitmapEx->Merge(vc_dest, *pSrcBitmapEx, vc_srcRect);
1155 // for removing compiler warnings
1156 return E_OPERATION_FAILED;
1160 _BitmapImpl::GetHeight() const
1162 if (!(INSTANCE_IS_VALID))
1164 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1168 if (_ResUtil::NeedToConvertCoord())
1170 return this->_sharedItem->coordHolder->bitmapSize.required.h;
1174 return this->_sharedItem->nativeBitmap->GetHeight();
1179 _BitmapImpl::GetWidth() const
1181 if (!(INSTANCE_IS_VALID))
1183 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1187 if (_ResUtil::NeedToConvertCoord())
1189 return this->_sharedItem->coordHolder->bitmapSize.required.w;
1193 return this->_sharedItem->nativeBitmap->GetWidth();
1198 _BitmapImpl::GetBitsPerPixel() const
1200 if (!(INSTANCE_IS_VALID))
1202 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1206 return this->_sharedItem->nativeBitmap->GetBitsPerPixel();
1210 _BitmapImpl::GetPixelColorFormat() const
1212 if (!(INSTANCE_IS_VALID))
1214 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1215 return BITMAP_PIXEL_FORMAT_MAX;
1218 return this->_sharedItem->nativeBitmap->GetPixelColorFormat();
1222 _BitmapImpl::SetMaskingColor(const Color* pColor)
1224 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1226 _UpdateBitmapTimeStamp(*this);
1228 return this->_sharedItem->nativeBitmap->SetMaskingColor(pColor);
1232 _BitmapImpl::GetMaskingColor(Color& color) const
1234 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1236 return this->_sharedItem->nativeBitmap->GetMaskingColor(color);
1240 _BitmapImpl::SetAlphaConstant(int opacity)
1242 if (INSTANCE_IS_VALID)
1244 _UpdateBitmapTimeStamp(*this);
1246 this->_sharedItem->nativeBitmap->SetAlphaConstant(opacity);
1251 _BitmapImpl::GetAlphaConstant(void) const
1253 return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetAlphaConstant() : -1;
1257 _BitmapImpl::SetScalingQuality(BitmapScalingQuality quality)
1259 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1263 case BITMAP_SCALING_QUALITY_LOW:
1264 case BITMAP_SCALING_QUALITY_MID:
1265 case BITMAP_SCALING_QUALITY_HIGH:
1268 return E_INVALID_ARG;
1271 _UpdateBitmapTimeStamp(*this);
1273 this->_sharedItem->nativeBitmap->SetScalingQuality(quality);
1278 BitmapScalingQuality
1279 _BitmapImpl::GetScalingQuality(void) const
1281 return (INSTANCE_IS_VALID) ? this->_sharedItem->nativeBitmap->GetScalingQuality() : BITMAP_SCALING_QUALITY_LOW;
1285 _BitmapImpl::IsNinePatchedBitmap(void) const
1287 if (!(INSTANCE_IS_VALID))
1289 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1293 _Bitmap* pRefBitmap = (this->_sharedItem->lazyScaling && this->_sharedItem->scaledNativeBitmap.get()) ? this->_sharedItem->scaledNativeBitmap.get() : this->_sharedItem->nativeBitmap.get();
1295 return pRefBitmap->IsNinePatchedBitmap();
1299 _BitmapImpl::SetAsImmutable(void)
1301 if (INSTANCE_IS_VALID)
1303 if (this->_sharedItem->isMutable)
1307 if (this->Lock(bi) == E_SUCCESS)
1309 _Util::Pixmap dstImage(bi.width, bi.height, bi.bitsPerPixel, (void*)bi.pPixels, bi.pitch);
1310 dstImage.ConvertPremultiplied();
1315 this->_sharedItem->isMutable = false;
1316 this->_sharedItem->nativeBitmap->__isPremultiplied = true;
1318 //?? this->_sharedItem->scaledNativeBitmap
1324 _BitmapImpl::IsMutable(void)
1326 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, false, "This instance is not constructed yet.");
1328 return this->_sharedItem->isMutable;
1332 _BitmapImpl::Lock(BufferInfo& info, long timeout)
1334 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1336 _UpdateBitmapTimeStamp(*this);
1338 return this->_sharedItem->nativeBitmap->Lock(info, timeout);
1342 _BitmapImpl::Unlock()
1344 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1346 result r = this->_sharedItem->nativeBitmap->Unlock();
1348 _UpdateBitmapTimeStamp(*this);
1350 if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1352 if (this->_sharedItem->scaledNativeBitmap.get())
1354 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1355 this->_sharedItem->scaledNativeBitmap->UpdateOpaqueInfo();
1363 _BitmapImpl::LockFast(BufferInfo& info, long timeout)
1365 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1367 _UpdateBitmapTimeStamp(*this);
1369 return this->_sharedItem->nativeBitmap->LockFast(info, timeout);
1373 _BitmapImpl::UnlockFast()
1375 SysTryReturnResult(NID_GRP, INSTANCE_IS_VALID, E_OPERATION_FAILED, "This instance is not constructed yet.");
1377 result r = this->_sharedItem->nativeBitmap->UnlockFast();
1379 _UpdateBitmapTimeStamp(*this);
1381 if ((r == E_SUCCESS) && (this->_sharedItem->lazyScaling))
1383 if (this->_sharedItem->scaledNativeBitmap.get())
1385 _UpdateScaledBitmapEx(this->_sharedItem->nativeBitmap.get(), this->_sharedItem->scaledNativeBitmap.get());
1393 _BitmapImpl::_SetCallback(void (* DestroyCallback)(void*), void* pDestroyCallbackParam,
1394 void (* LockCallback)(void*), void* pLockCallbackParam,
1395 void (* UnlockCallback)(void*), void* pUnlockCallbackParam)
1397 if (!(INSTANCE_IS_VALID))
1399 SysLog(NID_GRP, "[E_OPERATION_FAILED] This instance is not constructed yet.");
1403 _UpdateBitmapTimeStamp(*this);
1405 this->_sharedItem->pDestroyCallbackFunc = DestroyCallback;
1406 this->_sharedItem->pDestroyCallbackParam = pDestroyCallbackParam;
1408 this->_sharedItem->pLockCallbackFunc = LockCallback;
1409 this->_sharedItem->pLockCallbackParam = pLockCallbackParam;
1411 this->_sharedItem->pUnlockCallbackFunc = UnlockCallback;
1412 this->_sharedItem->pUnlockCallbackParam = pUnlockCallbackParam;
1414 if (this->_sharedItem->nativeBitmap.get())
1416 this->_sharedItem->nativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam);
1419 if (this->_sharedItem->scaledNativeBitmap.get())
1421 this->_sharedItem->scaledNativeBitmap->SetCallback(LockCallback, pLockCallbackParam, UnlockCallback, pUnlockCallbackParam);
1428 _BitmapImpl::GetExpandedBitmapN(const Bitmap& ninePatchedBitmap, int width, int height)
1430 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);
1432 SysTryReturn(NID_GRP, &ninePatchedBitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1434 const _BitmapImpl* pSrcBitmapImpl = _BitmapImpl::GetInstance(ninePatchedBitmap);
1436 SysTryReturn(NID_GRP, BITMAPIMPL_IS_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1438 SysTryReturn(NID_GRP, pSrcBitmapImpl->IsNinePatchedBitmap(), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is not a nine-patched bitmap");
1440 BitmapPixelFormat pixelFormat = pSrcBitmapImpl->GetPixelColorFormat();
1442 switch (pixelFormat)
1444 case BITMAP_PIXEL_FORMAT_RGB565:
1445 case BITMAP_PIXEL_FORMAT_ARGB8888:
1448 SysTryReturn(NID_GRP, false, null, E_UNSUPPORTED_FORMAT, "[E_UNSUPPORTED_FORMAT] Pixel format of the given bitmap is invalid (%d)", pixelFormat);
1452 std::auto_ptr<Bitmap> expandedBitmap(new (std::nothrow) Bitmap);
1454 SysTryReturn(NID_GRP, expandedBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1456 result r = expandedBitmap->Construct(Dimension(width, height), pixelFormat);
1458 SysTryReturn(NID_GRP, r == E_SUCCESS, null, r, "[%s] Propagating.", GetErrorMessage(r));
1460 _BitmapImpl* pDstBitmapImpl = _BitmapImpl::GetInstance(*expandedBitmap.get());
1462 SysAssert(pDstBitmapImpl != null);
1465 _Util::LockManager srcBitmap(*pSrcBitmapImpl);
1466 _Util::LockManager dstBitmap(*pDstBitmapImpl);
1468 SysTryReturn(NID_GRP, srcBitmap.IsValid(), null, srcBitmap.GetResult(), "[%s] Buffer locking of the source bitmap failed", srcBitmap.GetResult());
1469 SysTryReturn(NID_GRP, dstBitmap.IsValid(), null, dstBitmap.GetResult(), "[%s] Buffer locking of the target bitmap failed", dstBitmap.GetResult());
1471 if (dstBitmap.GetBufferInfo().width < srcBitmap.GetBufferInfo().width - 2 ||
1472 dstBitmap.GetBufferInfo().height < srcBitmap.GetBufferInfo().height - 2)
1474 // down-scales from the source bitmap only
1475 const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1476 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1478 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1480 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1482 Rectangle sourRect(1, 1, srcBufferInfo.width - 2, srcBufferInfo.height - 2);
1483 Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
1485 unsigned char* pSrcPixels = (unsigned char*) srcBufferInfo.pPixels + sourRect.y * srcBufferInfo.pitch + sourRect.x * (srcBufferInfo.bitsPerPixel / 8);
1486 _Util::Pixmap srcImage(sourRect.width, sourRect.height, srcBufferInfo.bitsPerPixel, (void*) pSrcPixels, srcBufferInfo.pitch);
1488 Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1492 const BufferInfo& srcBufferInfo = srcBitmap.GetBufferInfo();
1493 const BufferInfo& dstBufferInfo = dstBitmap.GetBufferInfo();
1495 memset(dstBufferInfo.pPixels, 0, dstBufferInfo.pitch * dstBufferInfo.height);
1497 _Util::Pixmap dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, (void*) dstBufferInfo.pPixels, dstBufferInfo.pitch);
1499 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > > boundsList;
1501 Rectangle destRect(0, 0, dstBufferInfo.width, dstBufferInfo.height);
1503 // assert(pSrcBitmapImpl->_nativeBitmap);
1504 r = _Util::GetPatchList(boundsList, destRect, *pSrcBitmapImpl->_sharedItem->nativeBitmap.get());
1506 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] _Util::GetPatchList() failed (error = %#x)", r);
1508 _Util::AccumList<_Util::Pair<_Util::Rectangle<int>, _Util::Rectangle<int> > >::Iterator iter = boundsList.Begin();
1510 while (iter != boundsList.End())
1512 Rectangle destRect(iter->first.x, iter->first.y, iter->first.w, iter->first.h);
1513 Rectangle sourRect(iter->second.x, iter->second.y, iter->second.w, iter->second.h);
1516 unsigned char* pSrcPixels = (unsigned char*) srcBufferInfo.pPixels + sourRect.y * srcBufferInfo.pitch + sourRect.x * (srcBufferInfo.bitsPerPixel / 8);
1517 _Util::Pixmap srcImage(sourRect.width, sourRect.height, srcBufferInfo.bitsPerPixel, (void*) pSrcPixels, srcBufferInfo.pitch);
1519 Tizen::Graphics::_Effect::ScaleImage(dstImage, destRect.x, destRect.y, destRect.width, destRect.height, srcImage, Tizen::Graphics::_Effect::ROP_COPY);
1527 return expandedBitmap.release();
1531 _BitmapImpl::GetColorReplacedBitmapN(const Bitmap& bitmap, const Color& replacedColor, const Color& newColor)
1533 SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1535 std::auto_ptr<Bitmap> pRetBitmap;
1538 Bitmap* pSrcBitmap = const_cast<Bitmap*>(&bitmap);
1541 pSrcBitmap->Lock(biSrc);
1543 pRetBitmap.reset(_BitmapUtil::CreateBitmapN(Dimension(biSrc.width, biSrc.height), biSrc.bitsPerPixel));
1545 if (pRetBitmap.get())
1548 pRetBitmap->Lock(biDst);
1550 if ((biSrc.pitch == biDst.pitch) && (biSrc.height == biDst.height))
1552 memcpy(biDst.pPixels, biSrc.pPixels, biDst.pitch * biDst.height);
1555 pRetBitmap->Unlock();
1558 pSrcBitmap->Unlock();
1560 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] New bitmap construction failed");
1563 BufferInfo bufferInfo;
1565 result r = pRetBitmap->Lock(bufferInfo);
1567 SysTryReturn(NID_GRP, r == E_SUCCESS, null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap cannot retrieve the own buffer address");
1569 if (bufferInfo.bitsPerPixel == 32)
1571 typedef unsigned long Pixel;
1573 Pixel keyColor = replacedColor.GetRGB32() & 0x00FFFFFF;
1574 Pixel chgColor = newColor.GetRGB32() & 0x00FFFFFF;
1575 Pixel* pBuffer = reinterpret_cast<Pixel*>(bufferInfo.pPixels);
1576 int padding = bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel - bufferInfo.width;
1578 Pixel keyAlpha = (newColor.GetRGB32() & 0xFF000000) >> 24;
1579 keyAlpha += (keyAlpha >> 7);
1583 for (int y = 0; y < bufferInfo.height; y++)
1585 for (int x = 0; x < bufferInfo.width; x++)
1587 // if buffer.rgb = replacedColor.rgb then begin
1588 // buffer.a <- buffer.a * newColor.a;
1589 // buffer.r <- newColor.r;
1590 // buffer.g <- newColor.g;
1591 // buffer.b <- newColor.b;
1594 if ((*pBuffer & 0x00FFFFFF) == keyColor)
1596 Pixel alpha = (*pBuffer >> 8) & 0x00FF0000;
1597 alpha = (alpha * keyAlpha) & 0xFF000000;
1599 *pBuffer = alpha | chgColor;
1610 for (int y = 0; y < bufferInfo.height; y++)
1612 for (int x = 0; x < bufferInfo.width; x++)
1614 // if buffer.rgb = replacedColor.rgb then begin
1615 // buffer.a <- buffer.a;
1616 // buffer.r <- newColor.r;
1617 // buffer.g <- newColor.g;
1618 // buffer.b <- newColor.b;
1621 if ((*pBuffer & 0x00FFFFFF) == keyColor)
1623 *pBuffer = (*pBuffer & 0xFF000000) | chgColor;
1633 else if (bufferInfo.bitsPerPixel == 16)
1635 typedef unsigned short Pixel;
1639 Pixel* pBuffer = reinterpret_cast<Pixel*>(bufferInfo.pPixels);
1640 int padding = bufferInfo.pitch * 8 / bufferInfo.bitsPerPixel - bufferInfo.width;
1643 unsigned long color32 = replacedColor.GetRGB32();
1644 _Effect::Func::ConvertColorFormatFast(&keyColor, &color32);
1648 unsigned long color32 = newColor.GetRGB32() & 0x00FFFFFF;
1649 _Effect::Func::ConvertColorFormatFast(&chgColor, &color32);
1652 for (int y = 0; y < bufferInfo.height; y++)
1654 for (int x = 0; x < bufferInfo.width; x++)
1656 if (*pBuffer == keyColor)
1658 *pBuffer = chgColor;
1672 pRetBitmap->Unlock();
1674 return pRetBitmap.release();
1678 _BitmapImpl::CloneN(const Bitmap& bitmap)
1680 const _BitmapImpl* pSrcBitmapImpl = null;
1681 _BitmapImpl* pDstBitmapImpl = null;
1683 // source bitmap verification
1685 SysTryReturn(NID_GRP, &bitmap, null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid (null reference passed)");
1687 pSrcBitmapImpl = _BitmapImpl::GetInstance(bitmap);
1689 SysTryReturn(NID_GRP, IS_BITMAPIMPL_VALID(pSrcBitmapImpl), null, E_INVALID_ARG, "[E_INVALID_ARG] The given bitmap is invalid");
1692 // destination bitmap allocation
1693 std::auto_ptr<Bitmap> pRetBitmap(new (std::nothrow) Bitmap);
1696 SysTryReturn(NID_GRP, pRetBitmap.get(), null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed (new Bitmap)");
1698 pDstBitmapImpl = _BitmapImpl::GetInstance(*pRetBitmap.get());
1700 SysTryReturn(NID_GRP, pDstBitmapImpl && pDstBitmapImpl->_sharedItem.get() && !pDstBitmapImpl->_sharedItem->nativeBitmap->IsValid(), null, E_SYSTEM, "[E_SYSTEM] The allocated bitmap is invalid");
1703 pDstBitmapImpl->_sharedItem = pSrcBitmapImpl->_sharedItem;
1705 return pRetBitmap.release();
1709 _BitmapImpl::GetNonScaledBitmapImplN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
1711 return _NonScale::CreateBitmapN(buffer, dim, pixelFormat);
1715 _BitmapImpl::GetNonScaledBitmapN(const Tizen::Base::ByteBuffer& buffer, const Dimension& dim, BitmapPixelFormat pixelFormat)
1717 _BitmapImpl* pBitmapImpl = _BitmapImpl::GetNonScaledBitmapImplN(buffer, dim, pixelFormat);
1719 if (pBitmapImpl == null)
1724 return Tizen::Graphics::_BitmapUtil::CreateBitmapN(pBitmapImpl);
1728 _BitmapImpl::_GetBitmapImpl(Bitmap* pBitmap)
1730 return pBitmap->__pImpl;
1734 _BitmapImpl::GetInstance(Bitmap& bitmap)
1736 return (&bitmap != null) ? bitmap.__pImpl : null;
1740 _BitmapImpl::GetInstance(const Bitmap& bitmap)
1742 return (&bitmap != null) ? bitmap.__pImpl : null;
1746 _BitmapImpl::__CheckValidity(bool canBufferExpand)
1748 if (this->_sharedItem.get())
1750 if (this->_sharedItem->nativeBitmap->IsValid())
1755 if (!this->_sharedItem->associated.fileName.IsEmpty())
1757 if (canBufferExpand)
1759 if (!__RealizeBuffer())
1761 // linkedFileName does not exist or is not a image file.
1762 this->Construct(Dimension(1, 1), BITMAP_PIXEL_FORMAT_ARGB8888);
1765 this->_sharedItem->associated.fileName.Clear();
1776 _BitmapImpl::__RealizeBuffer(void)
1779 int imageHeight = 0;
1781 Tizen::Media::MediaPixelFormat format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
1783 // The following does not consider the case of big-endian
1784 switch (this->_sharedItem->associated.pixelFormat)
1786 case BITMAP_PIXEL_FORMAT_RGB565:
1787 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGB565LE;
1789 case BITMAP_PIXEL_FORMAT_R8G8B8A8:
1790 format = Tizen::Media::MEDIA_PIXEL_FORMAT_RGBA8888;
1792 case BITMAP_PIXEL_FORMAT_ARGB8888:
1794 format = Tizen::Media::MEDIA_PIXEL_FORMAT_BGRA8888;
1798 std::auto_ptr<ByteBuffer> pImageBuffer(Tizen::Media::_ImageDecoder::DecodeToBufferN(this->_sharedItem->associated.fileName, format, imageWidth, imageHeight));
1800 if (pImageBuffer.get() == null)
1805 std::auto_ptr<_BitmapImpl> pTempBitmapImpl(_BitmapImpl::GetNonScaledBitmapImplN(*pImageBuffer, Dimension(imageWidth, imageHeight), this->_sharedItem->associated.pixelFormat));
1807 if (pTempBitmapImpl.get() == null || pTempBitmapImpl->_sharedItem.get() == null)
1812 pImageBuffer.reset();
1814 this->_sharedItem->Move(*(pTempBitmapImpl->_sharedItem.get()));
1819 void _BitmapImpl::_SharedItem::Move(_BitmapImpl::_SharedItem& source)
1821 std::swap(this->nativeBitmap, source.nativeBitmap);
1822 std::swap(this->coordHolder, source.coordHolder);
1823 std::swap(this->lazyScaling, source.lazyScaling);
1824 std::swap(this->scaledNativeBitmap, source.scaledNativeBitmap);
1825 std::swap(this->isMutable, source.isMutable);
1828 }} // Tizen::Graphics