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_UtilPixmap.cpp
20 * @brief This is the implementation file for internal util class.
28 #include <unique_ptr.h>
30 #include <FBaseDataType.h>
31 #include <FBaseSysLog.h>
33 #include "FGrp_UtilTemplate.h"
34 #include "FGrp_UtilPixmap.h"
36 using namespace Tizen::Graphics;
38 ////////////////////////////////////////////////////////////////////////////////
41 _Util::Pixmap::Pixmap()
48 enableColorKey = false;
50 enableReplaceColor = false;
58 _Util::Pixmap::Pixmap(int _width, int _height, int _depth, int _bytesPerLine)
64 bytesPerLine = _bytesPerLine,
65 enableColorKey = false;
67 enableReplaceColor = false;
74 if (bytesPerLine == 0)
76 bytesPerLine = width * depth / 8;
79 pBitmap = new (std::nothrow) unsigned char[bytesPerLine * height];
81 SysTryReturnVoidResult(NID_GRP, pBitmap, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
83 // ¸ðµç °ÍÀÌ ¼º°øÇßÀ» ¶§¸¸ 1ÀÇ °ªÀ» °¡Áö°Ô µÈ´Ù.
87 _Util::Pixmap::Pixmap(int _width, int _height, int _depth, void* _pBitmap, int _bytesPerLine)
93 bytesPerLine = _bytesPerLine,
94 enableColorKey = false;
96 enableReplaceColor = false;
100 pBitmap = (unsigned char*) _pBitmap;
103 if (bytesPerLine == 0)
105 bytesPerLine = width * depth / 8;
109 _Util::Pixmap::Pixmap(PixmapBase& refImage)
111 memcpy(this, &refImage, sizeof(*this));
112 refImage.reserved = 0;
115 _Util::Pixmap::Pixmap(const PixmapBase& refImage)
117 memcpy(this, &refImage, sizeof(*this));
121 _Util::Pixmap::Pixmap(const Pixmap& refImage)
123 memcpy(this, &refImage, sizeof(*this));
127 _Util::Pixmap::~Pixmap()
136 _Util::Pixmap::operator =(const Pixmap& refImage)
138 if (this == &refImage)
143 PixmapBase::operator =(refImage);
145 refImage.reserved = 0;
151 _Util::Pixmap::GetSubBitmap(long x, long y, long w, long h) const
158 x1 = (x1 < 0) ? 0 : x1;
159 y1 = (y1 < 0) ? 0 : y1;
160 x2 = (x2 > width) ? width : x2;
161 y2 = (y2 > height) ? height : y2;
163 PixmapBase retImage((PixmapBase &) * this);
164 ((PixmapBase*) this)->reserved = retImage.reserved;
165 retImage.reserved = 0;
167 retImage.pBitmap += retImage.bytesPerLine * y1 + x1 * depth / 8;
168 retImage.width = x2 - x1;
169 retImage.height = y2 - y1;
175 _Util::Pixmap::GetSubBitmapUnsafe(long x, long y, long w, long h) const
177 PixmapBase retImage((PixmapBase &) * this);
178 ((PixmapBase*) this)->reserved = retImage.reserved;
179 retImage.reserved = 0;
181 retImage.pBitmap += retImage.bytesPerLine * y + x * depth / 8;
191 template<typename DestPixel, typename SourPixel>
193 _ConvertColorFormat(DestPixel* pDest, SourPixel* pSour, int count)
195 DestPixel* pDestEnd = pDest + count;
197 while (pDest < pDestEnd)
206 inline unsigned long*
207 _ConvertColorFormat(unsigned long* pDest, unsigned short* pSour, int count)
209 typedef unsigned short SourPixel;
210 typedef unsigned long DestPixel;
212 DestPixel* pDestEnd = pDest + count;
214 while (pDest < pDestEnd)
216 DestPixel r = (*pSour & 0xF800) >> 8;
217 DestPixel g = (*pSour & 0x07E0) >> 3;
218 DestPixel b = (*pSour & 0x001F) << 3;
224 *pDest++ = 0xFF000000 | (r << 16) | (g << 8) | (b);
232 inline unsigned short*
233 _ConvertColorFormat(unsigned short* pDest, unsigned long* pSour, int count)
235 typedef unsigned long SourPixel;
236 typedef unsigned short DestPixel;
238 DestPixel* pDestEnd = pDest + count;
240 while (pDest < pDestEnd)
242 DestPixel r = (DestPixel) ((*pSour & 0xF80000) >> 8);
243 DestPixel g = (DestPixel) ((*pSour & 0x00FC00) >> 5);
244 DestPixel b = (DestPixel) ((*pSour & 0x0000F8) >> 3);
246 *pDest++ = r | g | b;
253 template<typename DestPixel, typename SourPixel>
255 ConvertBitmap(const _Util::Pixmap& srcBitmap)
257 std::unique_ptr<DestPixel[]> buffer(new (std::nothrow) DestPixel[srcBitmap.width * srcBitmap.height]);
259 SysTryReturn(NID_GRP, buffer, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
261 DestPixel* pDest = (DestPixel*) buffer.get();
262 SourPixel* pSour = (SourPixel*) srcBitmap.pBitmap;
263 long pitch = (srcBitmap.bytesPerLine / sizeof(SourPixel));
265 for (int y = 0; y < srcBitmap.height; y++)
267 pDest = _ConvertColorFormat(pDest, pSour, srcBitmap.width);
271 return buffer.release();
275 _CreatePremultipliedBuffer(const _Util::Pixmap& srcImage)
277 typedef unsigned long DestPixel;
279 if (srcImage.depth != 32)
282 std::unique_ptr<unsigned char[]> destBuffer(new (std::nothrow) unsigned char[srcImage.width * srcImage.height * sizeof(DestPixel)]);
284 DestPixel* pDestBuffer = reinterpret_cast<DestPixel*>(destBuffer.get());
288 if (srcImage.bytesPerLine == int(srcImage.width * sizeof(DestPixel)))
290 memcpy(pDestBuffer, srcImage.pBitmap, srcImage.bytesPerLine * srcImage.height);
294 DestPixel* pSrc = (DestPixel*)srcImage.pBitmap;
295 DestPixel* pDst = (DestPixel*)pDestBuffer;
297 long srcPitch = (srcImage.bytesPerLine * 8 / srcImage.depth);
298 long dstPitch = srcImage.width;
300 for (int y = 0; y < srcImage.height; y++)
302 memcpy(pDst, pSrc, srcImage.width * sizeof(DestPixel));
308 DestPixel* p = (DestPixel*)pDestBuffer;
311 for (int y = 0; y < srcImage.height; y++)
313 for (int x = 0; x < srcImage.width; x++)
315 DestPixel a = (*p) & 0xFF000000;
316 DestPixel r = (*p >> 8) & 0x0000FF00;
317 DestPixel g = (*p >> 8) & 0x000000FF;
318 DestPixel b = (*p) & 0x000000FF;
320 DestPixel mul = (a >> 24) + (a >> 31);
322 r = (r * mul) & 0x00FF0000;
323 g = (g * mul) & 0x0000FF00;
324 b = (b * mul) & 0x0000FF00;
326 *p++ = a | r | g | (b >> 8);
333 return destBuffer.release();
339 _Util::Pixmap::GetClone(unsigned long depth) const
342 if ((this->pBitmap == null) || (this->width <= 0) || (this->height <= 0))
348 void* pConvertedBuffer = null;
350 if (depth == 32 && this->depth == 32)
352 pConvertedBuffer = (void*) ConvertBitmap <unsigned long, unsigned long>(*this);
354 else if (depth == 32 && this->depth == 16)
356 pConvertedBuffer = (void*) ConvertBitmap <unsigned long, unsigned short>(*this);
358 else if (depth == 16 && this->depth == 32)
360 pConvertedBuffer = (void*) ConvertBitmap <unsigned short, unsigned long>(*this);
362 else if (depth == 16 && this->depth == 16)
364 pConvertedBuffer = (void*) ConvertBitmap <unsigned short, unsigned short>(*this);
367 if (pConvertedBuffer == null)
372 _Util::Pixmap* pImageEx = new (std::nothrow) _Util::Pixmap(this->width, this->height, depth, pConvertedBuffer, this->width * depth / 8);
374 SysTryReturn(NID_GRP, pImageEx, pImageEx, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] The memory is insufficient.");
376 pImageEx->reserved = 1;
382 _Util::Pixmap::GetPremultipliedPixmap(void) const
385 if ((this->pBitmap == null) || (this->width <= 0) || (this->height <= 0))
391 if (this->depth == 32)
393 std::auto_ptr<_Util::Pixmap> temp(new (std::nothrow) _Util::Pixmap(*this));
394 std::unique_ptr<unsigned char[]> buffer(_CreatePremultipliedBuffer(*this));
396 if (temp.get() && buffer.get())
398 temp->pBitmap = buffer.release();
399 temp->bytesPerLine = temp->width * temp->depth / 8;
402 return temp.release();
411 return GetClone(this->depth);
416 _Util::Pixmap::ConvertPremultiplied(void)
418 if (this->pBitmap == null || this->depth != 32)
421 if (this->isPremultiplied)
424 typedef unsigned long DestPixel;
426 DestPixel* p = reinterpret_cast<DestPixel*>(this->pBitmap);
427 long paddingBytes = this->bytesPerLine - this->width * this->depth / 8;
429 for (int y = 0; y < this->height; y++)
431 for (int x = 0; x < this->width; x++)
433 DestPixel a = (*p) & 0xFF000000;
434 DestPixel r = (*p >> 8) & 0x0000FF00;
435 DestPixel g = (*p >> 8) & 0x000000FF;
436 DestPixel b = (*p) & 0x000000FF;
438 DestPixel mul = (a >> 24) + (a >> 31);
440 r = (r * mul) & 0x00FF0000;
441 g = (g * mul) & 0x0000FF00;
442 b = (b * mul) & 0x0000FF00;
444 *p++ = a | r | g | (b >> 8);
447 p = reinterpret_cast<DestPixel*>(reinterpret_cast<unsigned char*>(p) + paddingBytes);