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_EffectScale.cpp
20 * @brief This is the header file for internal utility class.
26 #include <FBaseSysLog.h>
28 #include "FGrp_EffectFunc.h"
29 #include "FGrp_Effect.h"
30 #include "../util/FGrp_Util.h"
32 using namespace Tizen::Graphics;
38 template<typename Pixel>
39 class _GenericBufferPixmap
40 : public _Util::GenericBufferBase <Pixel>
43 inline _GenericBufferPixmap(const _Util::PixmapBase& buffer, const _Util::Rectangle<int>* pRect)
44 : _Util::GenericBufferBase <Pixel>()
47 this->_pBuffer = (Pixel*) __buffer.pBitmap;
48 this->_pitch = __buffer.bytesPerLine / sizeof(Pixel);
52 this->_padding = this->_pitch - pRect->w;
53 this->_pBuffer += (this->_pitch * pRect->y + pRect->x);
54 this->_rect.x = pRect->x;
55 this->_rect.y = pRect->y;
56 this->_rect.w = pRect->w;
57 this->_rect.h = pRect->h;
61 this->_padding = this->_pitch - __buffer.width;
64 this->_rect.w = __buffer.width;
65 this->_rect.h = __buffer.height;
69 inline virtual ~_GenericBufferPixmap(void)
74 const _Util::PixmapBase& __buffer;
77 typedef unsigned long FIXED16x16;
79 template<typename Pixel>
81 _ScaleImageUnclipped(_Util::PixmapBase* pRetImage, _Util::PixmapBase* pSrcImage, Pixel dummy = 0)
83 if (pRetImage == null || pSrcImage == null)
88 if ((pSrcImage->width <= 0) || (pSrcImage->height <= 0)
89 || (pRetImage->width <= 0) || (pRetImage->height <= 0))
94 _Util::GenericBuffer <Pixel> srcBuffer(new (std::nothrow) _GenericBufferPixmap <Pixel>(*pSrcImage, null));
95 _Util::GenericBuffer <Pixel> dstBuffer(new (std::nothrow) _GenericBufferPixmap <Pixel>(*pRetImage, null));
97 SysTryReturn(NID_GRP, srcBuffer.IsValid() && dstBuffer.IsValid(), false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
100 FIXED16x16 ySour = 0;
101 FIXED16x16 wScale = FIXED16x16(srcBuffer.GetWidth() * 0x10000 / dstBuffer.GetWidth());
102 FIXED16x16 hScale = FIXED16x16(srcBuffer.GetHeight() * 0x10000 / dstBuffer.GetHeight());
106 Pixel* pDest = dstBuffer.GetBufferAddr();
109 int hCopy = dstBuffer.GetHeight();
114 pSour = srcBuffer.GetBufferAddr() + int(ySour >> 16) * srcBuffer.GetPitch();
115 wCopy = dstBuffer.GetWidth();
123 pSour += (int(xSour >> 16) - int(temp >> 16));
126 pDest += dstBuffer.GetPadding();
133 template<typename DestPixel, typename SourPixel>
135 _ScaleImageCopyClipped(_Util::PixmapBase* pRetImage, _Util::PixmapBase* pSrcImage, const _Util::Rectangle<int>& validRect,
136 DestPixel dummy1 = 0,
137 SourPixel dummy2 = 0)
139 if (pRetImage == null || pSrcImage == null)
144 if ((pSrcImage->width <= 0) || (pSrcImage->height <= 0)
145 || (pRetImage->width <= 0) || (pRetImage->height <= 0))
150 _Util::GenericBuffer <SourPixel> srcBuffer(new (std::nothrow) _GenericBufferPixmap <SourPixel>(*pSrcImage, null));
151 _Util::GenericBuffer <DestPixel> dstBuffer(new (std::nothrow) _GenericBufferPixmap <DestPixel>(*pRetImage, null));
153 SysTryReturn(NID_GRP, srcBuffer.IsValid() && dstBuffer.IsValid(), false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
155 FIXED16x16 xSour = 0;
156 FIXED16x16 ySour = 0;
157 FIXED16x16 wScale = FIXED16x16(srcBuffer.GetWidth() * 0x10000 / dstBuffer.GetWidth());
158 FIXED16x16 hScale = FIXED16x16(srcBuffer.GetHeight() * 0x10000 / dstBuffer.GetHeight());
162 DestPixel* pDest = dstBuffer.GetBufferAddr();
164 int wCopy = validRect.x + validRect.w;
165 int hCopy = validRect.y + validRect.h;
167 for (int yDest = 0; yDest < hCopy; ++yDest)
169 if (yDest < validRect.y)
171 int jump = (validRect.y - yDest);
173 pDest += (dstBuffer.GetPitch() * jump);
174 ySour += (hScale * jump);
179 pSour = srcBuffer.GetBufferAddr() + int(ySour >> 16) * srcBuffer.GetPitch();
182 int jump = validRect.x;
185 xSour += (wScale * jump);
186 pSour += (int(xSour >> 16));
189 if (!pSrcImage->enableColorKey)
191 for (int xDest = validRect.x; xDest < wCopy; xDest++)
193 _Effect::Func::ConvertColorFormatFast <DestPixel, SourPixel>(pDest, pSour);
198 pSour += (int(xSour >> 16) - int(temp >> 16));
203 SourPixel colorKey = (SourPixel) pSrcImage->colorKey;
205 for (int xDest = validRect.x; xDest < wCopy; xDest++)
207 if (*pSour != colorKey)
209 _Effect::Func::ConvertColorFormatFast <DestPixel, SourPixel>(pDest, pSour);
216 pSour += (int(xSour >> 16) - int(temp >> 16));
220 pDest += (dstBuffer.GetWidth() - wCopy);
221 pDest += dstBuffer.GetPadding();
229 template<typename DestPixel, typename SourPixel>
231 _ScaleImageClipped(_Util::PixmapBase* pRetImage, _Util::PixmapBase* pSrcImage, const _Util::Rectangle<int>& validRect,
232 DestPixel dummy1 = 0, SourPixel dummy2 = 0)
234 if (pRetImage == null || pSrcImage == null)
239 if ((pSrcImage->width <= 0) || (pSrcImage->height <= 0)
240 || (pRetImage->width <= 0) || (pRetImage->height <= 0))
245 _Util::GenericBuffer <SourPixel> srcBuffer(new (std::nothrow) _GenericBufferPixmap <SourPixel>(*pSrcImage, null));
246 _Util::GenericBuffer <DestPixel> dstBuffer(new (std::nothrow) _GenericBufferPixmap <DestPixel>(*pRetImage, null));
248 SysTryReturn(NID_GRP, srcBuffer.IsValid() && dstBuffer.IsValid(), false, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
250 FIXED16x16 xSour = 0;
251 FIXED16x16 ySour = 0;
252 FIXED16x16 wScale = FIXED16x16(srcBuffer.GetWidth() * 0x10000 / dstBuffer.GetWidth());
253 FIXED16x16 hScale = FIXED16x16(srcBuffer.GetHeight() * 0x10000 / dstBuffer.GetHeight());
256 SourPixel* pSour = 0;
257 DestPixel* pDest = dstBuffer.GetBufferAddr();
259 int wCopy = validRect.x + validRect.w;
260 int hCopy = validRect.y + validRect.h;
262 for (int yDest = 0; yDest < hCopy; ++yDest)
264 if (yDest < validRect.y)
266 int jump = (validRect.y - yDest);
268 pDest += (dstBuffer.GetPitch() * jump);
269 ySour += (hScale * jump);
274 pSour = srcBuffer.GetBufferAddr() + int(ySour >> 16) * srcBuffer.GetPitch();
277 int jump = validRect.x;
280 xSour += (wScale * jump);
281 pSour += (int(xSour >> 16));
284 if (!pSrcImage->enableColorKey)
286 for (int xDest = validRect.x; xDest < wCopy; xDest++)
288 // _Effect::Func::ConvertColorFormatFast<DestPixel, SourPixel>(pDest, pSour);
289 *pDest = _Effect::Func::AlphaBlendingFast <DestPixel, SourPixel>(*pDest, *pSour);
294 pSour += (int(xSour >> 16) - int(temp >> 16));
299 SourPixel colorKey = (SourPixel) pSrcImage->colorKey;
301 for (int xDest = validRect.x; xDest < wCopy; xDest++)
303 if (*pSour != colorKey)
305 *pDest = _Effect::Func::AlphaBlendingFast <DestPixel, SourPixel>(*pDest, *pSour);
312 pSour += (int(xSour >> 16) - int(temp >> 16));
316 pDest += (dstBuffer.GetWidth() - wCopy);
317 pDest += dstBuffer.GetPadding();
326 _ScaleImage(const _Util::Pixmap& retImage, long xDest, long yDest, long wDest, long hDest, const _Util::Pixmap& srcImage,
329 _Util::Rectangle<int> outRect = {0, 0, -1, -1};
332 _Util::Rectangle<int> dstRect = { 0, 0, retImage.width, retImage.height };
333 _Util::Rectangle<int> tgtRect = { xDest, yDest, wDest, hDest };
337 bool hasRegion = IntersectRect(outRect, tgtRect, dstRect);
339 SM_ASSERT(hasRegion);
342 IntersectRect(outRect, tgtRect, dstRect);
345 // workaround 2010/3/6
346 // variable: bool isUnclipped = false;
347 // isUnclipped = (tgtRect == outRect);
351 #if 0 // isUnclipped is always false
354 _Util::PixmapBase dstImage = retImage.GetSubBitmap(xDest, yDest, wDest, hDest);
356 switch (retImage.depth)
359 return _ScaleImageUnclipped <unsigned long>((_Util::PixmapBase*) &dstImage, (_Util::PixmapBase*) &srcImage);
362 return _ScaleImageUnclipped <unsigned short>((_Util::PixmapBase*) &dstImage, (_Util::PixmapBase*) &srcImage);
371 _Util::PixmapBase dstImage = retImage.GetSubBitmapUnsafe(xDest, yDest, wDest, hDest);
372 _Util::Rectangle<int> validRect = outRect;
374 validRect.x -= xDest;
375 validRect.y -= yDest;
379 case Tizen::Graphics::_Effect::ROP_COPY:
380 switch (retImage.depth)
383 if (srcImage.depth == 32)
385 return _ScaleImageCopyClipped <unsigned long, unsigned long>((_Util::PixmapBase*) &dstImage,
386 (_Util::PixmapBase*) &srcImage, validRect,
387 (unsigned long) 0, (unsigned long) 0);
389 else if (srcImage.depth == 16)
391 return _ScaleImageCopyClipped <unsigned long, unsigned short>((_Util::PixmapBase*) &dstImage,
392 (_Util::PixmapBase*) &srcImage, validRect,
393 (unsigned long) 0, (unsigned short) 0);
400 if (srcImage.depth == 32)
402 return _ScaleImageCopyClipped <unsigned short, unsigned long>((_Util::PixmapBase*) &dstImage,
403 (_Util::PixmapBase*) &srcImage, validRect,
404 (unsigned short) 0, (unsigned long) 0);
406 else if (srcImage.depth == 16)
408 return _ScaleImageCopyClipped <unsigned short, unsigned short>((_Util::PixmapBase*) &dstImage,
409 (_Util::PixmapBase*) &srcImage, validRect,
410 (unsigned short) 0, (unsigned short) 0);
420 case Tizen::Graphics::_Effect::ROP_ALPHABLEND:
421 switch (retImage.depth)
424 if (srcImage.depth == 32)
426 return _ScaleImageClipped <unsigned long, unsigned long>((_Util::PixmapBase*) &dstImage,
427 (_Util::PixmapBase*) &srcImage, validRect,
428 (unsigned long) 0, (unsigned long) 0);
430 else if (srcImage.depth == 16)
432 return _ScaleImageClipped <unsigned long, unsigned short>((_Util::PixmapBase*) &dstImage,
433 (_Util::PixmapBase*) &srcImage, validRect,
434 (unsigned long) 0, (unsigned short) 0);
441 if (srcImage.depth == 32)
443 return _ScaleImageClipped <unsigned short, unsigned long>((_Util::PixmapBase*) &dstImage,
444 (_Util::PixmapBase*) &srcImage, validRect,
445 (unsigned short) 0, (unsigned long) 0);
447 else if (srcImage.depth == 16)
449 return _ScaleImageClipped <unsigned short, unsigned short>((_Util::PixmapBase*) &dstImage,
450 (_Util::PixmapBase*) &srcImage, validRect,
451 (unsigned short) 0, (unsigned short) 0);
472 Tizen::Graphics::_Effect::ScaleImage(_Util::Pixmap& dstImage, long xDest, long yDest, long wDest, long hDest,
473 const _Util::Pixmap& srcImage,
476 // verifiy the spcified parameters
478 if ((srcImage.width < 0) || (srcImage.height < 0) || (srcImage.pBitmap == null))
483 if ((dstImage.width < 0) || (dstImage.height < 0) || (dstImage.pBitmap == null))
488 if ((wDest < 0) || (hDest < 0))
493 if (srcImage.pBitmap == dstImage.pBitmap)
498 if (!(rop == ROP_COPY || rop == ROP_ALPHABLEND))
505 if ((srcImage.width == 0) || (srcImage.height == 0))
510 if ((dstImage.width == 0) || (dstImage.height == 0))
515 if ((wDest == 0) || (hDest == 0))
521 _Util::Rectangle<int> dstRect = { 0, 0, dstImage.width, dstImage.height };
522 _Util::Rectangle<int> tgtRect = { xDest, yDest, wDest, hDest };
523 _Util::Rectangle<int> outRect;
525 if (!IntersectRect(outRect, tgtRect, dstRect))
532 return _ScaleImage(dstImage, xDest, yDest, wDest, hDest, srcImage, rop);