bool wxDIB::Create(const wxImage& image, PixelFormat pf)
{
- wxCHECK_MSG( image.Ok(), false, wxT("invalid wxImage in wxDIB ctor") );
+ wxCHECK_MSG( image.IsOk(), false, wxT("invalid wxImage in wxDIB ctor") );
const int h = image.GetHeight();
const int w = image.GetWidth();
unsigned char *dst = dstLineStart;
if ( alpha )
{
+ int x;
+
switch ( pf )
{
case PixelFormat_PreMultiplied:
// Pre-multiply pixel values so that the DIB could be used
// with ::AlphaBlend().
- for ( int x = 0; x < w; x++ )
+ for ( x = 0; x < w; x++ )
{
const unsigned char a = *alpha++;
*dst++ = (unsigned char)((src[2] * a + 127) / 255);
case PixelFormat_NotPreMultiplied:
// Just copy pixel data without changing it.
- for ( int x = 0; x < w; x++ )
+ for ( x = 0; x < w; x++ )
{
*dst++ = src[2];
*dst++ = src[1];
const int w = GetWidth();
const int h = GetHeight();
wxImage image(w, h, false /* don't bother clearing memory */);
- if ( !image.Ok() )
+ if ( !image.IsOk() )
{
wxFAIL_MSG( wxT("could not allocate data for image") );
return wxNullImage;
}
const int bpp = GetDepth();
+
+ // Remember if we have any "real" transparency, i.e. either any partially
+ // transparent pixels or not all pixels are fully opaque or fully
+ // transparent.
bool hasAlpha = false;
+ bool hasOpaque = false;
+ bool hasTransparent = false;
+
if ( bpp == 32 )
{
// 32 bit bitmaps may be either 0RGB or ARGB and we don't know in
// premultiplication done in Create() above
const unsigned char a = *src;
*alpha++ = a;
+
+ // Check what kind of alpha do we have.
+ switch ( a )
+ {
+ case 0:
+ hasTransparent = true;
+ break;
+
+ default:
+ // Anything in between means we have real transparency
+ // and must use alpha channel.
+ hasAlpha = true;
+ break;
+
+ case 255:
+ hasOpaque = true;
+ break;
+ }
+
if ( a > 0 )
{
dst[0] = (dst[0] * 255) / a;
dst[1] = (dst[1] * 255) / a;
dst[2] = (dst[2] * 255) / a;
-
- hasAlpha = true;
}
src++;
srcLineStart += srcBytesPerLine;
}
+ if ( hasOpaque && hasTransparent )
+ hasAlpha = true;
+
if ( !hasAlpha && image.HasAlpha() )
image.ClearAlpha();