From 254f9b4c3c485a35d817d464bd94b04b18e6fc3b Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 24 Oct 2010 22:40:22 +0000 Subject: [PATCH] Fix conversion of 32 bit ARGB bitmaps to wxImage in wxMSW. wxDIB::m_hasAlpha can't be trusted when the DIB was loaded from a file so don't rely on it in wxDIB::ConvertToImage(). Instead, suppose that 32 bpp bitmaps do have alpha channel and only get rid of it at the end of conversion if it turns out that all alpha values were 0. Closes #10133. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65898 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/dib.cpp | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/msw/dib.cpp b/src/msw/dib.cpp index be10fcf047..3675d7e8a0 100644 --- a/src/msw/dib.cpp +++ b/src/msw/dib.cpp @@ -748,20 +748,25 @@ wxImage wxDIB::ConvertToImage() const return wxNullImage; } - if ( m_hasAlpha ) + const int bpp = GetDepth(); + bool hasAlpha = false; + if ( bpp == 32 ) { + // 32 bit bitmaps may be either 0RGB or ARGB and we don't know in + // advance which one do we have so suppose we have alpha of them and + // get rid of it later if it turns out we didn't (in particular, don't + // trust m_hasAlpha which is not set correctly when the image was + // loaded from file). image.SetAlpha(); } // this is the same loop as in Create() just above but with copy direction // reversed - const int bpp = GetDepth(); const int dstBytesPerLine = w * 3; const int srcBytesPerLine = GetLineSize(w, bpp); unsigned char *dst = image.GetData() + ((h - 1) * dstBytesPerLine); unsigned char *alpha = image.HasAlpha() ? image.GetAlpha() + (h - 1)*w : NULL; - const bool is32bit = bpp == 32; const unsigned char *srcLineStart = (unsigned char *)GetData(); for ( int y = 0; y < h; y++ ) { @@ -773,20 +778,19 @@ wxImage wxDIB::ConvertToImage() const dst[1] = *src++; dst[0] = *src++; - if ( is32bit ) + if ( bpp == 32 ) { - if ( alpha ) + // wxImage uses non premultiplied alpha so undo + // premultiplication done in Create() above + const unsigned char a = *src; + *alpha++ = a; + if ( a > 0 ) { - // wxImage uses non premultiplied alpha so undo - // premultiplication done in Create() above - const unsigned char a = *src; - *alpha++ = a; - if ( a > 0 ) - { - dst[0] = (dst[0] * 255) / a; - dst[1] = (dst[1] * 255) / a; - dst[2] = (dst[2] * 255) / a; - } + dst[0] = (dst[0] * 255) / a; + dst[1] = (dst[1] * 255) / a; + dst[2] = (dst[2] * 255) / a; + + hasAlpha = true; } src++; @@ -804,6 +808,9 @@ wxImage wxDIB::ConvertToImage() const srcLineStart += srcBytesPerLine; } + if ( !hasAlpha && image.HasAlpha() ) + image.ClearAlpha(); + return image; }