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_EffectScale2.cpp
20 * @brief This is the header file for internal utility class.
26 #include "FGrp_Effect.h"
39 return (x - float(ix)) > 0 ? ix + 1 : ix;
58 return (float(ix) - x) > 0 ? ix - 1 : ix;
71 operator ==(const _Rectangle& lhs, const _Rectangle& rhs)
73 return (lhs.x == rhs.x) && (lhs.y == rhs.y) && (lhs.w == rhs.w) && (lhs.h == rhs.h);
78 int width; // width of image
79 int height; // height of image
80 int bytesPerLine; // bytes per line
81 int depth; // pixel depth of buffer
82 unsigned char* pBitmap; // start pointer to buffer
83 mutable long reserved; // do you have ownership?
89 BufferDescUtil(int width, int height, int depth, void* pBitmap, int bytesPerLine = 0)
92 this->height = height;
94 this->bytesPerLine = bytesPerLine,
95 this->pBitmap = (unsigned char*) pBitmap;
98 if (bytesPerLine == 0)
100 this->bytesPerLine = width * depth / 8;
104 ~BufferDescUtil(void)
106 // if 'reserved' is not 0, buffer is released automatically
113 _BufferDesc GetSubBitmapUnsafe(long x, long y, long w, long h) const
115 _BufferDesc retImage((_BufferDesc&) *this);
116 ((_BufferDesc*) this)->reserved = retImage.reserved;
117 retImage.reserved = 0;
119 retImage.pBitmap += retImage.bytesPerLine * y + x * depth / 8;
127 BufferDescUtil(const BufferDescUtil& rhs);
128 BufferDescUtil& operator=(const BufferDescUtil& rhs);
132 template<typename SrcIter, typename DstIter>
134 _Copy(SrcIter pFirst, SrcIter pLast, DstIter pTarget)
136 for ( ; pFirst != pLast; ++pTarget, ++pFirst)
144 template<typename BaseType>
148 explicit _SmartArray(unsigned char* pBuffer = 0)
149 : __hasOwnership(pBuffer != 0)
150 , __pPtr((BaseType*)pBuffer)
158 delete[] (unsigned char*) __pPtr;
162 BaseType& operator [](unsigned int index) const
164 return __pPtr[index];
167 void Bind(unsigned char* pBuffer)
171 __hasOwnership = (pBuffer != 0);
172 __pPtr = (BaseType*) pBuffer;
176 BaseType* Get() const
181 BaseType* Release() const
183 ((_SmartArray <BaseType>*) this)->__hasOwnership = false;
197 namespace Tizen { namespace Graphics
203 namespace Interpolation
208 const float CONST_2_0 = 2.0f;
209 const float CONST_1_5 = 1.5f;
210 const float CONST_1_0 = 1.0f;
211 const float CONST_0_75 = 0.75f;
212 const float CONST_0_5 = 0.5f;
213 const float CONST_0_0 = 0.0f;
214 const float CONST_MINUS_0_5 = -0.5f;
215 const float CONST_MINUS_1_0 = -1.0f;
223 // memory allocation as a byte array
224 static inline unsigned char*
225 AllocMem(size_t size)
227 return new (std::nothrow) unsigned char[size];
241 const Filter FILTER_GOOD = FILTER_BICUBIC;
242 const Filter FILTER_BEST = FILTER_MITCHELL;
244 // offset of the color component as the applied endian
247 #if defined(BIG_ENDIAN)
261 ////////////////////////////////////////////////////////////////////////////
264 template <typename Pixel, int offset>
265 struct ScaleImageDesc
267 ScaleImageDesc(long x, long y, long bytesPerLine, Pixel* pData);
268 inline unsigned char GetPixel(long x, long y) const;
269 inline void PutPixel(long x, long y, unsigned char pixel);
273 unsigned char* pData;
278 ////////////////////////////////////////////////////////////////////////////
279 // ScaleImageDesc<unsigned long>
283 ScaleImageDesc<unsigned long, OFFSET_RED>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned long* pData)
286 , pData((unsigned char*)pData + OFFSET_RED)
294 ScaleImageDesc<unsigned long, OFFSET_RED>::GetPixel(long x, long y) const
296 return pData[y * span + x * OFFSET_STRIDE];
301 ScaleImageDesc<unsigned long, OFFSET_RED>::PutPixel(long x, long y, unsigned char pixel)
303 pData[y * span + x * OFFSET_STRIDE] = pixel;
308 ScaleImageDesc<unsigned long, OFFSET_GREEN>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned long* pData)
311 , pData((unsigned char*)pData + OFFSET_GREEN)
319 ScaleImageDesc<unsigned long, OFFSET_GREEN>::GetPixel(long x, long y) const
321 return pData[y * span + x * OFFSET_STRIDE];
326 ScaleImageDesc<unsigned long, OFFSET_GREEN>::PutPixel(long x, long y, unsigned char pixel)
328 pData[y * span + x * OFFSET_STRIDE] = pixel;
333 ScaleImageDesc<unsigned long, OFFSET_BLUE>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned long* pData)
336 , pData((unsigned char*)pData + OFFSET_BLUE)
344 ScaleImageDesc<unsigned long, OFFSET_BLUE>::GetPixel(long x, long y) const
346 return pData[y * span + x * OFFSET_STRIDE];
351 ScaleImageDesc<unsigned long, OFFSET_BLUE>::PutPixel(long x, long y, unsigned char pixel)
353 pData[y * span + x * OFFSET_STRIDE] = pixel;
358 ScaleImageDesc<unsigned long, OFFSET_ALPHA>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned long* pData)
361 , pData((unsigned char*)pData + OFFSET_ALPHA)
369 ScaleImageDesc<unsigned long, OFFSET_ALPHA>::GetPixel(long x, long y) const
371 return pData[y * span + x * OFFSET_STRIDE];
376 ScaleImageDesc<unsigned long, OFFSET_ALPHA>::PutPixel(long x, long y, unsigned char pixel)
378 pData[y * span + x * OFFSET_STRIDE] = pixel;
381 ////////////////////////////////////////////////////////////////////////////
382 // ScaleImageDesc<unsigned short>
386 ScaleImageDesc<unsigned short, OFFSET_RED>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned short* pData)
389 , pData((unsigned char*)pData)
397 ScaleImageDesc<unsigned short, OFFSET_RED>::GetPixel(long x, long y) const
399 return (*((unsigned short*)&pData[y * span + x * 2]) >> 11) & 0x001F;
404 ScaleImageDesc<unsigned short, OFFSET_RED>::PutPixel(long x, long y, unsigned char pixel)
406 unsigned short* pBuf = (unsigned short*)&pData[y * span + x * 2];
407 unsigned short color = (unsigned short)((pixel > 0x001F) ? 0x001F : pixel);
408 *pBuf = (*pBuf & ~0xF800) | ((color << 11) & 0xF800);
413 ScaleImageDesc<unsigned short, OFFSET_GREEN>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned short* pData)
416 , pData((unsigned char*)pData)
424 ScaleImageDesc<unsigned short, OFFSET_GREEN>::GetPixel(long x, long y) const
426 return (*((unsigned short*)&pData[y * span + x * 2]) >> 5) & 0x003F;
431 ScaleImageDesc<unsigned short, OFFSET_GREEN>::PutPixel(long x, long y, unsigned char pixel)
433 unsigned short* pBuf = (unsigned short*)&pData[y * span + x * 2];
434 unsigned short color = (unsigned short)((pixel > 0x003F) ? 0x003F : pixel);
435 *pBuf = (*pBuf & ~0x07E0) | ((color << 5) & 0x07E0);
440 ScaleImageDesc<unsigned short, OFFSET_BLUE>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned short* pData)
443 , pData((unsigned char*)pData)
451 ScaleImageDesc<unsigned short, OFFSET_BLUE>::GetPixel(long x, long y) const
453 return (*((unsigned short*)&pData[y * span + x * 2])) & 0x001F;
458 ScaleImageDesc<unsigned short, OFFSET_BLUE>::PutPixel(long x, long y, unsigned char pixel)
460 unsigned short* pBuf = (unsigned short*)&pData[y * span + x * 2];
461 unsigned short color = (unsigned short)((pixel > 0x001F) ? 0x001F : pixel);
462 *pBuf = (*pBuf & ~0x001F) | (color & 0x001F);
467 ScaleImageDesc<unsigned short, OFFSET_ALPHA>::ScaleImageDesc(long x, long y, long bytesPerLine, unsigned short* pData)
470 , pData((unsigned char*)pData)
478 ScaleImageDesc<unsigned short, OFFSET_ALPHA>::GetPixel(long x, long y) const
485 ScaleImageDesc<unsigned short, OFFSET_ALPHA>::PutPixel(long x, long y, unsigned char pixel)
489 ////////////////////////////////////////////////////////////////////////////
492 template <Filter FilterType>
495 inline static float Apply(float t);
496 inline static float Width(void);
499 ////////////////////////////////////
500 // FilterDesc - FILTER_BOX
504 struct FilterDesc<FILTER_BOX>
506 inline static float Apply(float t)
508 return ((t > CONST_MINUS_0_5) && t <= CONST_0_5) ? CONST_1_0 : CONST_0_0;
511 inline static float Width(void)
517 ////////////////////////////////////
518 // FilterDesc - FILTER_TRIANGLE
522 struct FilterDesc<FILTER_TRIANGLE>
524 inline static float Apply(float t)
526 t = (t >= CONST_0_0) ? t : -t;
527 return (t < CONST_1_0) ? (float(CONST_1_0) - t) : CONST_0_0;
530 inline static float Width(void)
536 ////////////////////////////////////
537 // FilterDesc - FILTER_BICUBIC
541 struct FilterDesc<FILTER_BICUBIC>
543 inline static float Apply(float t)
545 t = (t >= CONST_0_0) ? t : -t;
546 return (t < CONST_1_0) ? float((t * CONST_2_0 - MakeConst(3)) * t * t + CONST_1_0) : CONST_0_0;
549 inline static float Width(void)
555 ////////////////////////////////////
556 // FilterDesc - FILTER_BELL
558 // bell curve, normal curve alike
560 struct FilterDesc<FILTER_BELL>
562 inline static float Apply(float t)
564 // box (*) box (*) box
565 t = (t >= CONST_0_0) ? t : -t;
569 return float(CONST_0_75 - (t * t));
575 return float((t * t) * CONST_0_5);
581 inline static float Width(void)
587 ////////////////////////////////////
588 // FilterDesc - FILTER_BSPLINE
590 // B-Spline interpolation, blurred
592 struct FilterDesc<FILTER_BSPLINE>
594 inline static float Apply(float t)
596 // box (*) box (*) box (*) box
597 t = (t >= CONST_0_0) ? t : -t;
602 return float((tt * t * CONST_0_5) - tt + (float(CONST_2_0) / MakeConst(3)));
608 return float((float(CONST_1_0) / MakeConst(6)) * (t * t * t));
614 inline static float Width(void)
620 ////////////////////////////////////
621 // FilterDesc - FILTER_MITCHELL
623 // interpolation + high-pass filter
625 struct FilterDesc<FILTER_MITCHELL>
627 inline static float Apply(float t)
629 const float b = float(CONST_1_0) / float(MakeConst(3));
630 const float c = float(CONST_1_0) / float(MakeConst(3));
634 t = (t >= CONST_0_0) ? t : -t;
638 t = float(((MakeConst(12) - b * MakeConst(9) - c * MakeConst(6)) * (t * tt))+((b * MakeConst(12) + c * MakeConst(6) - MakeConst(18)) * tt) + (MakeConst(6) - b * CONST_2_0));
639 return float(t / MakeConst(6));
644 t = float(((b * CONST_MINUS_1_0 - c * MakeConst(6)) * (t * tt)) + ((b * MakeConst(6) + c * MakeConst(30)) * tt) + ((b * MakeConst(-12) - c * MakeConst(48)) * t) + (b * MakeConst(8) + c * MakeConst(24)));
645 return float(t / MakeConst(6));
651 inline static float Width(void)
657 ////////////////////////////////////////////////////////////////////////////
660 // store pixel values and filtered weights
679 ELEMENT_SIZE = sizeof(Element)
682 // store pixel value and weight
683 inline void Push(int x, int max, float weight)
690 pArray[total].pixel = (x < max) ? x : max - 1 - x % max;
691 pArray[total].weight = weight;
696 template <Filter defaultFilter>
697 inline void FillToExpand(int center, int xSize)
701 int left = (int)_Ceil(float(center) - FilterDesc<defaultFilter>::Width());
702 int right = (int)_Floor(float(center) + FilterDesc<defaultFilter>::Width());
704 for (int j = left; j <= right; ++j)
706 Push(j, xSize, FilterDesc<defaultFilter>::Apply(float(center) - float(j)));
711 template <Filter defaultFilter>
712 inline void FillToShrink(int center, int xSize, float Width, float scale)
716 int left = (int)_Ceil(float(center) - Width);
717 int right = (int)_Floor(float(center) + Width);
719 for (int j = left; j <= right; ++j)
721 Push(j, xSize, FilterDesc<defaultFilter>::Apply((float(center) - float(j)) / scale) / scale);
726 // normalize as interger(0~255) from thw weight as float
728 PixelOfWeight(float weight)
730 if (weight <= CONST_0_0)
737 if (weight - float(p) >= CONST_0_5)
742 return (p >= 255) ? 255 : (unsigned char)p;
745 template <Filter DefaultFilter, typename Pixel>
747 ScaleImage(_BufferDesc* pDstImage, long wDest, int hDest, _BufferDesc* pSrcImage, const _Rectangle& validRect)
751 Pixel* pSrcBuffer = (Pixel*)pSrcImage->pBitmap;
752 Pixel* pDstBuffer = 0;
754 long xSrcSize = pSrcImage->width;
755 long ySrcSize = pSrcImage->height;
757 _SmartArray<ScaleArray::Element> localArray;
758 _SmartArray<ScaleArray::Element> arrayMem;
760 // store pre-calculated pixel index and weight for all columns
761 _SmartArray<ScaleArray> ypwArrays(AllocMem(hDest * sizeof(ScaleArray)));
763 if (ypwArrays.Get() == 0)
768 ScaleArray* pYpwArraysEnd = ypwArrays.Get() + hDest;
770 if (hDest < ySrcSize)
772 // in case of shrinking for the y axis
773 float width = float(ySrcSize) * FilterDesc<DefaultFilter>::Width() / float(hDest);
774 float scalingRatio = float(ySrcSize) / float(hDest);
775 size_t pwaSize = (size_t)float(width * CONST_2_0 + CONST_1_0);
777 localArray.Bind(AllocMem(pwaSize * ScaleArray::ELEMENT_SIZE * hDest));
779 if (localArray.Get() == 0)
784 ScaleArray::Element* pArray = localArray.Get();
786 for (int yDst = 0; yDst < hDest; ++yDst)
788 ypwArrays[yDst].pArray = pArray;
790 ypwArrays[yDst].FillToShrink<DefaultFilter>(yDst * ySrcSize / hDest, ySrcSize, width, scalingRatio);
795 // in case of expanding for the y axis
796 size_t pwaSize = size_t(FilterDesc<DefaultFilter>::Width() * CONST_2_0 + CONST_1_0);
798 localArray.Bind(AllocMem(pwaSize * ScaleArray::ELEMENT_SIZE * hDest));
800 if (localArray.Get() == 0)
805 ScaleArray::Element* pArray = localArray.Get();
807 for (int yDst = 0; yDst < hDest; ++yDst)
809 ypwArrays[yDst].pArray = pArray;
811 ypwArrays[yDst].FillToExpand<DefaultFilter>(yDst * ySrcSize / hDest, ySrcSize);
815 // allocate the pixel weight array within the one row
817 float width = float(xSrcSize) * FilterDesc<DefaultFilter>::Width() / float(wDest);
818 float scalingRatio = float(xSrcSize) / float(wDest);
819 bool xShrink = (wDest < xSrcSize);
823 // in case of shrinking for the x axis
824 arrayMem.Bind(AllocMem((size_t)(width * CONST_2_0 + CONST_1_0) * ScaleArray::ELEMENT_SIZE));
828 // in case of expanding for the x axis
829 arrayMem.Bind(AllocMem((size_t)(FilterDesc<DefaultFilter>::Width() * CONST_2_0 + CONST_1_0) * ScaleArray::ELEMENT_SIZE));
832 if (arrayMem.Get() == 0)
837 xpwArray.pArray = arrayMem.Get();
839 // allocate memory for each color component
840 _SmartArray<unsigned char> column(AllocMem(4 * ySrcSize * sizeof(unsigned char)));
842 if (column.Get() == 0)
847 unsigned char* pColumnA = column.Get();
848 unsigned char* pColumnR = pColumnA + ySrcSize;
849 unsigned char* pColumnG = pColumnR + ySrcSize;
850 unsigned char* pColumnB = pColumnG + ySrcSize;
852 // divide color components for the source
853 ScaleImageDesc<Pixel, OFFSET_ALPHA> aSrc(xSrcSize, ySrcSize, pSrcImage->bytesPerLine, pSrcBuffer);
854 ScaleImageDesc<Pixel, OFFSET_RED> rSrc(xSrcSize, ySrcSize, pSrcImage->bytesPerLine, pSrcBuffer);
855 ScaleImageDesc<Pixel, OFFSET_GREEN> gSrc(xSrcSize, ySrcSize, pSrcImage->bytesPerLine, pSrcBuffer);
856 ScaleImageDesc<Pixel, OFFSET_BLUE> bSrc(xSrcSize, ySrcSize, pSrcImage->bytesPerLine, pSrcBuffer);
859 pDstBuffer = (Pixel*)pDstImage->pBitmap;
861 // divide color components for the destination
862 ScaleImageDesc<Pixel, OFFSET_ALPHA> aDst(wDest, hDest, pDstImage->bytesPerLine, pDstBuffer);
863 ScaleImageDesc<Pixel, OFFSET_RED> rDst(wDest, hDest, pDstImage->bytesPerLine, pDstBuffer);
864 ScaleImageDesc<Pixel, OFFSET_GREEN> gDst(wDest, hDest, pDstImage->bytesPerLine, pDstBuffer);
865 ScaleImageDesc<Pixel, OFFSET_BLUE> bDst(wDest, hDest, pDstImage->bytesPerLine, pDstBuffer);
868 for (int xDst = 0; xDst < wDest; ++xDst)
870 if ((xDst < validRect.x) || (xDst >= validRect.x + validRect.w))
875 // calculate weight for one color component column
878 xpwArray.FillToShrink<DefaultFilter>(xDst * xSrcSize / wDest, xSrcSize, width, scalingRatio);
882 xpwArray.FillToExpand<DefaultFilter>(xDst * xSrcSize / wDest, xSrcSize);
885 ScaleArray::Element* pXaEnd = xpwArray.pArray + xpwArray.total; // total is known at this line
890 // Apply horiz FilterDesc to make rDst column in pColumnR
891 for (int ySrc = 0; ySrc < ySrcSize; ++ySrc)
893 pixel = xpwArray.pArray->pixel;
894 weight = xpwArray.pArray->weight;
896 bool aPixelsSame = true;
897 bool rPixelsSame = true;
898 bool gPixelsSame = true;
899 bool bPixelsSame = true;
901 unsigned char a = aSrc.GetPixel(pixel, ySrc);
902 unsigned char r = rSrc.GetPixel(pixel, ySrc);
903 unsigned char g = gSrc.GetPixel(pixel, ySrc);
904 unsigned char b = bSrc.GetPixel(pixel, ySrc);
906 float aWeight = float(a) * weight;
907 float rWeight = float(r) * weight;
908 float gWeight = float(g) * weight;
909 float bWeight = float(b) * weight;
911 for (ScaleArray::Element* pXa = xpwArray.pArray + 1; pXa < pXaEnd; ++pXa)
914 weight = pXa->weight;
916 unsigned char a2 = aSrc.GetPixel(pixel, ySrc);
917 unsigned char r2 = rSrc.GetPixel(pixel, ySrc);
918 unsigned char g2 = gSrc.GetPixel(pixel, ySrc);
919 unsigned char b2 = bSrc.GetPixel(pixel, ySrc);
921 aPixelsSame &= (a2 == a);
922 rPixelsSame &= (r2 == r);
923 gPixelsSame &= (g2 == g);
924 bPixelsSame &= (b2 == b);
926 aWeight += float(a2) * weight;
927 rWeight += float(r2) * weight;
928 gWeight += float(g2) * weight;
929 bWeight += float(b2) * weight;
932 pColumnA[ySrc] = aPixelsSame ? a : PixelOfWeight(aWeight);
933 pColumnR[ySrc] = rPixelsSame ? r : PixelOfWeight(rWeight);
934 pColumnG[ySrc] = gPixelsSame ? g : PixelOfWeight(gWeight);
935 pColumnB[ySrc] = bPixelsSame ? b : PixelOfWeight(bWeight);
938 // The temp column has been built. Now stretch it vertically into xDst column
939 for (ScaleArray* pYpwArray = ypwArrays.Get(); pYpwArray < pYpwArraysEnd; ++pYpwArray)
941 int yDst = (int)(pYpwArray - ypwArrays.Get());
943 if ((yDst < validRect.y) || (yDst >= validRect.y + validRect.h))
948 ScaleArray::Element* pYa = pYpwArray->pArray;
949 ScaleArray::Element* pYaEnd = pYa + pYpwArray->total;
952 weight = pYa->weight;
954 bool aPixelsSame = true;
955 bool rPixelsSame = true;
956 bool gPixelsSame = true;
957 bool bPixelsSame = true;
959 unsigned char a = pColumnA[pixel];
960 unsigned char r = pColumnR[pixel];
961 unsigned char g = pColumnG[pixel];
962 unsigned char b = pColumnB[pixel];
964 float aWeight = float(a) * weight;
965 float rWeight = float(r) * weight;
966 float gWeight = float(g) * weight;
967 float bWeight = float(b) * weight;
971 for (; pYa < pYaEnd; ++pYa)
973 if ((weight = pYa->weight) > 0)
977 unsigned char a2 = pColumnA[pixel];
978 unsigned char r2 = pColumnR[pixel];
979 unsigned char g2 = pColumnG[pixel];
980 unsigned char b2 = pColumnB[pixel];
982 aPixelsSame &= (a2 == a);
983 rPixelsSame &= (r2 == r);
984 gPixelsSame &= (g2 == g);
985 bPixelsSame &= (b2 == b);
987 aWeight += float(a2) * weight;
988 rWeight += float(r2) * weight;
989 gWeight += float(g2) * weight;
990 bWeight += float(b2) * weight;
995 aDst.PutPixel(xDst, yDst, aPixelsSame ? a : PixelOfWeight(aWeight));
996 rDst.PutPixel(xDst, yDst, rPixelsSame ? r : PixelOfWeight(rWeight));
997 gDst.PutPixel(xDst, yDst, gPixelsSame ? g : PixelOfWeight(gWeight));
998 bDst.PutPixel(xDst, yDst, bPixelsSame ? b : PixelOfWeight(bWeight));
1012 namespace Interpolation
1016 IntersectRect(_Rectangle& outRect, const _Rectangle& srcRect1, const _Rectangle& srcRect2)
1025 LocalBound(const _Rectangle& rect)
1028 , x2(rect.x + rect.w)
1029 , y2(rect.y + rect.h)
1034 LocalBound srcBound1(srcRect1);
1035 LocalBound srcBound2(srcRect2);
1037 if (((srcRect1.w > 0 && srcRect1.h > 0) && (srcRect2.w > 0 && srcRect2.h > 0))
1038 && ((srcBound2.x2 > srcBound1.x1) && (srcBound2.x1 < srcBound1.x2) && (srcBound2.y2 > srcBound1.y1) && (srcBound2.y1 < srcBound1.y2)))
1040 outRect.x = (srcBound2.x1 <= srcBound1.x1) ? srcBound1.x1 : srcBound2.x1;
1041 outRect.y = (srcBound2.y1 <= srcBound1.y1) ? srcBound1.y1 : srcBound2.y1;
1042 outRect.w = ((srcBound2.x2 >= srcBound1.x2) ? srcBound1.x2 : srcBound2.x2) - outRect.x;
1043 outRect.h = ((srcBound2.y2 >= srcBound1.y2) ? srcBound1.y2 : srcBound2.y2) - outRect.y;
1059 ScaleImage(const BufferDescUtil& retImage, long xDest, long yDest, long wDest, long hDest, const BufferDescUtil& srcImage, DefaultFilter defaultFilter)
1064 _Rectangle dstRect = { 0, 0, retImage.width, retImage.height };
1065 _Rectangle tgtRect = { xDest, yDest, wDest, hDest };
1068 bool hasRegion = IntersectRect(outRect, tgtRect, dstRect);
1077 _BufferDesc dstImage = retImage.GetSubBitmapUnsafe(xDest, yDest, wDest, hDest);
1078 _Rectangle validRect = outRect;
1080 validRect.x -= xDest;
1081 validRect.y -= yDest;
1083 switch (defaultFilter)
1085 case DEFAULT_FILTER_GOOD:
1086 switch (retImage.depth)
1089 return _Effect::Interpolation::ScaleImage<FILTER_GOOD, unsigned long>((_BufferDesc*)&dstImage, wDest, hDest, (_BufferDesc*)&srcImage, validRect);
1091 return _Effect::Interpolation::ScaleImage<FILTER_GOOD, unsigned short>((_BufferDesc*)&dstImage, wDest, hDest, (_BufferDesc*)&srcImage, validRect);
1096 case DEFAULT_FILTER_BEST:
1098 switch (retImage.depth)
1101 return _Effect::Interpolation::ScaleImage<FILTER_BEST, unsigned long>((_BufferDesc*)&dstImage, wDest, hDest, (_BufferDesc*)&srcImage, validRect);
1103 return _Effect::Interpolation::ScaleImage<FILTER_BEST, unsigned short>((_BufferDesc*)&dstImage, wDest, hDest, (_BufferDesc*)&srcImage, validRect);
1116 }} // Tizen::Graphics
1119 #include "../util/FGrp_Util.h"
1121 using namespace Tizen::Graphics;
1124 Tizen::Graphics::_Effect::ScaleImageInterpolation(_Util::Pixmap& dstImage, long xDest, long yDest, long wDest, long hDest,
1125 const _Util::Pixmap& srcImage, DefaultFilter defaultFilter)
1127 // verifiy the spcified parameters
1129 if ((srcImage.width < 0) || (srcImage.height < 0) || (srcImage.pBitmap == null))
1134 if ((dstImage.width < 0) || (dstImage.height < 0) || (dstImage.pBitmap == null))
1139 if ((wDest < 0) || (hDest < 0))
1144 if (srcImage.pBitmap == dstImage.pBitmap)
1151 if ((srcImage.width == 0) || (srcImage.height == 0))
1156 if ((dstImage.width == 0) || (dstImage.height == 0))
1161 if ((wDest == 0) || (hDest == 0))
1167 _Util::Rectangle<int> dstRect =
1175 _Util::Rectangle<int> tgtRect =
1183 _Util::Rectangle<int> outRect;
1185 if (!IntersectRect(outRect, tgtRect, dstRect))
1192 BufferDescUtil srcBuffer(srcImage.width, srcImage.height, srcImage.depth, srcImage.pBitmap, srcImage.bytesPerLine);
1193 BufferDescUtil dstBuffer(dstImage.width, dstImage.height, dstImage.depth, dstImage.pBitmap, dstImage.bytesPerLine);
1195 return _Effect::Interpolation::ScaleImage(dstBuffer, 0, 0, dstImage.width, dstImage.height, srcBuffer, defaultFilter);
1198 ////////////////////////////////////////////////////////////////////////////////
1199 // API for test case
1203 #include <FGrpBitmap.h>
1205 namespace Tizen { namespace Graphics
1208 result _BitmapScale(Bitmap& dstBitmap, int scaleWidth, int scaleHeight)
1211 #define CHECK_THROW(cond, rslt) if (!(cond)) { r = rslt; break; }
1213 result r = E_SUCCESS;
1217 _SmartArray<unsigned char> srcBuffer;
1219 BufferInfo srcBufferInfo;
1220 BufferInfo dstBufferInfo;
1222 result r = dstBitmap.Lock(srcBufferInfo);
1224 CHECK_THROW(r == E_SUCCESS, r);
1226 srcBuffer.Bind(new (std::nothrow) unsigned char[srcBufferInfo.pitch * srcBufferInfo.height]);
1228 CHECK_THROW(srcBuffer.Get() && srcBufferInfo.pPixels, E_OUT_OF_MEMORY);
1230 // same as memcpy(srcBuffer.Get(), srcBufferInfo.pPixels, srcBufferInfo.pitch * srcBufferInfo.height);
1232 unsigned char* pBegin = static_cast<unsigned char*>(srcBufferInfo.pPixels);
1233 unsigned char* pEnd = pBegin + srcBufferInfo.pitch * srcBufferInfo.height;
1234 unsigned char* pTarget = srcBuffer.Get();
1236 _Copy(pBegin, pEnd, pTarget);
1239 srcBufferInfo.pPixels = (void*)srcBuffer.Get();
1243 r = dstBitmap.Scale(Dimension(scaleWidth, scaleHeight));
1245 CHECK_THROW(r == E_SUCCESS, r);
1247 r = dstBitmap.Lock(dstBufferInfo);
1249 CHECK_THROW(r == E_SUCCESS, r);
1251 BufferDescUtil srcImage(srcBufferInfo.width, srcBufferInfo.height, srcBufferInfo.bitsPerPixel, srcBufferInfo.pPixels, srcBufferInfo.pitch);
1252 BufferDescUtil dstImage(dstBufferInfo.width, dstBufferInfo.height, dstBufferInfo.bitsPerPixel, dstBufferInfo.pPixels, dstBufferInfo.pitch);
1254 _Effect::Interpolation::ScaleImage(dstImage, 0, 0, dstBufferInfo.width, dstBufferInfo.height, srcImage);
1266 }} // Tizen::Graphics