Utility function of _Util::Pixmap enforced. (regarding alpha attenuation)
authorYoungki Ahn <ykahn@samsung.com>
Sat, 6 Apr 2013 07:13:16 +0000 (16:13 +0900)
committerYoungki Ahn <ykahn@samsung.com>
Sat, 6 Apr 2013 07:13:16 +0000 (16:13 +0900)
Change-Id: I5b124d7ec6be2a670641a4100b1f6953d89b841d
Signed-off-by: Youngki Ahn <ykahn@samsung.com>
src/graphics/util/FGrp_UtilPixmap.cpp
src/graphics/util/FGrp_UtilPixmap.h

index 39a5e04..2bcfd58 100755 (executable)
@@ -333,6 +333,100 @@ _CreatePremultipliedBuffer(const _Util::Pixmap& srcImage)
        return destBuffer.release();
 }
 
+unsigned char*
+_CreateAlphaAttenuatedBuffer(const _Util::Pixmap& srcImage, int alphaConstant)
+{
+       typedef unsigned long DestPixel;
+
+       if (srcImage.depth != 32)
+               return null;
+
+       std::unique_ptr<unsigned char[]> destBuffer(new (std::nothrow) unsigned char[srcImage.width * srcImage.height * sizeof(DestPixel)]);
+
+       DestPixel* pDestBuffer = reinterpret_cast<DestPixel*>(destBuffer.get());
+
+       if (pDestBuffer)
+       {
+               if (alphaConstant <= 0)
+               {
+                       memset(pDestBuffer, 0, srcImage.bytesPerLine * srcImage.height);
+                       return destBuffer.release();
+               }
+
+               if (srcImage.bytesPerLine == int(srcImage.width * sizeof(DestPixel)))
+               {
+                       memcpy(pDestBuffer, srcImage.pBitmap, srcImage.bytesPerLine * srcImage.height);
+               }
+               else
+               {
+                       DestPixel* pSrc = (DestPixel*)srcImage.pBitmap;
+                       DestPixel* pDst = (DestPixel*)pDestBuffer;
+
+                       long srcPitch = (srcImage.bytesPerLine * 8 / srcImage.depth);
+                       long dstPitch = srcImage.width;
+
+                       for (int y = 0; y < srcImage.height; y++)
+                       {
+                               memcpy(pDst, pSrc, srcImage.width * sizeof(DestPixel));
+                               pSrc += srcPitch;
+                               pDst += dstPitch;
+                       }
+               }
+
+               if (alphaConstant >= 255)
+               {
+                       return destBuffer.release();
+               }
+
+               DestPixel attenuation = alphaConstant;
+               attenuation += (attenuation >> 7);
+
+               DestPixel* p = (DestPixel*)pDestBuffer;
+               long padding = 0;
+
+               if (!srcImage.isPremultiplied)
+               {
+                       for (int y = 0; y < srcImage.height; y++)
+                       {
+                               for (int x = 0; x < srcImage.width; x++)
+                               {
+                                       DestPixel alpha = ((*p) & 0xFF000000) >> 8;
+                                       alpha *= attenuation;
+
+                                       *p++ = (alpha & 0xFF000000) | ((*p) & 0x00FFFFFF);
+                               }
+
+                               p += padding;
+                       }
+               }
+               else
+               {
+                       for (int y = 0; y < srcImage.height; y++)
+                       {
+                               for (int x = 0; x < srcImage.width; x++)
+                               {
+                                       DestPixel a = (*p >> 8) & 0x00FF0000;
+                                       DestPixel r = (*p >> 8) & 0x0000FF00;
+                                       DestPixel g = (*p >> 8) & 0x000000FF;
+                                       DestPixel b = (*p) & 0x000000FF;
+
+                                       a = (a * attenuation) & 0xFF000000;
+                                       r = (r * attenuation) & 0x00FF0000;
+                                       g = (g * attenuation) & 0x0000FF00;
+                                       b = (b * attenuation) & 0x0000FF00;
+
+                                       *p++ = a | r | g | (b >> 8);
+
+                               }
+
+                               p += padding;
+                       }
+               }
+       }
+
+       return destBuffer.release();
+}
+
 }
 
 _Util::Pixmap*
@@ -412,6 +506,40 @@ _Util::Pixmap::GetPremultipliedPixmap(void) const
        }
 }
 
+_Util::Pixmap*
+_Util::Pixmap::GetAlphaAttenuatedPixmap(int alphaConstant) const
+{
+       {
+               if ((this->pBitmap == null) || (this->width <= 0) || (this->height <= 0))
+               {
+                       return null;
+               }
+       }
+
+       if (this->depth == 32)
+       {
+               std::auto_ptr<_Util::Pixmap> temp(new (std::nothrow) _Util::Pixmap(*this));
+               std::unique_ptr<unsigned char[]> buffer(_CreateAlphaAttenuatedBuffer(*this, alphaConstant));
+
+               if (temp.get() && buffer.get())
+               {
+                       temp->pBitmap = buffer.release();
+                       temp->bytesPerLine = temp->width * temp->depth / 8;
+                       temp->reserved = 1;
+
+                       return temp.release();
+               }
+               else
+               {
+                       return null;
+               }
+       }
+       else
+       {
+               return GetClone(this->depth);
+       }
+}
+
 void
 _Util::Pixmap::ConvertPremultiplied(void)
 {
index 36eb5dd..7aec53f 100755 (executable)
@@ -66,8 +66,11 @@ struct Pixmap
 
        PixmapBase GetSubBitmap(long x, long y, long w, long h) const;
        PixmapBase GetSubBitmapUnsafe(long x, long y, long w, long h) const;
+
        Pixmap* GetClone(unsigned long depth) const;
        Pixmap* GetPremultipliedPixmap(void) const;
+       Pixmap* GetAlphaAttenuatedPixmap(int alphaConstant) const;
+
        void ConvertPremultiplied(void);
        void ConvertNonpremultiplied(void);
 };