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*
}
}
+_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)
{