Allow creating DIBs storing pixels in non-premultiplied format in wxMSW.
wxDIB assumed that MSW always uses bitmaps in pre-multiplied pixel format but this turns out to be wrong: some Windows functions such as ImageList_Draw() or CreateIconIndirect() apply pre-multiplication internally and so must be given data in non-pre-multiplied format on input. This commit adds a possibility to create wxDIB in such format but doesn't use it anywhere yet, this will be done in subsequent commits. See #9050. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@65959 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -138,12 +138,28 @@ public:
|
|||||||
// ------------------
|
// ------------------
|
||||||
|
|
||||||
#if wxUSE_IMAGE
|
#if wxUSE_IMAGE
|
||||||
// create a DIB from the given image, the DIB will be either 24 or 32 (if
|
// Possible formats for DIBs created by the functions below.
|
||||||
// the image has alpha channel) bpp
|
enum PixelFormat
|
||||||
wxDIB(const wxImage& image) { Init(); (void)Create(image); }
|
{
|
||||||
|
PixelFormat_PreMultiplied = 0,
|
||||||
|
PixelFormat_NotPreMultiplied = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a DIB from the given image, the DIB will be either 24 or 32 (if
|
||||||
|
// the image has alpha channel) bpp.
|
||||||
|
//
|
||||||
|
// By default the DIB stores pixel data in pre-multiplied format so that it
|
||||||
|
// can be used with ::AlphaBlend() but it is also possible to disable
|
||||||
|
// pre-multiplication for the DIB to be usable with ImageList_Draw() which
|
||||||
|
// does pre-multiplication internally.
|
||||||
|
wxDIB(const wxImage& image, PixelFormat pf = PixelFormat_PreMultiplied)
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
(void)Create(image, pf);
|
||||||
|
}
|
||||||
|
|
||||||
// same as the above ctor but with the return code
|
// same as the above ctor but with the return code
|
||||||
bool Create(const wxImage& image);
|
bool Create(const wxImage& image, PixelFormat pf = PixelFormat_PreMultiplied);
|
||||||
|
|
||||||
// create wxImage having the same data as this DIB
|
// create wxImage having the same data as this DIB
|
||||||
wxImage ConvertToImage() const;
|
wxImage ConvertToImage() const;
|
||||||
|
@@ -658,7 +658,7 @@ wxPalette *wxDIB::CreatePalette() const
|
|||||||
|
|
||||||
#if wxUSE_IMAGE
|
#if wxUSE_IMAGE
|
||||||
|
|
||||||
bool wxDIB::Create(const wxImage& image)
|
bool wxDIB::Create(const wxImage& image, PixelFormat pf)
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( image.Ok(), false, wxT("invalid wxImage in wxDIB ctor") );
|
wxCHECK_MSG( image.Ok(), false, wxT("invalid wxImage in wxDIB ctor") );
|
||||||
|
|
||||||
@@ -683,27 +683,46 @@ bool wxDIB::Create(const wxImage& image)
|
|||||||
unsigned char *dstLineStart = (unsigned char *)m_data;
|
unsigned char *dstLineStart = (unsigned char *)m_data;
|
||||||
for ( int y = 0; y < h; y++ )
|
for ( int y = 0; y < h; y++ )
|
||||||
{
|
{
|
||||||
// copy one DIB line
|
// Copy one DIB line. Note that RGB components order is reversed in
|
||||||
|
// Windows bitmaps compared to wxImage and is actually BGR.
|
||||||
unsigned char *dst = dstLineStart;
|
unsigned char *dst = dstLineStart;
|
||||||
if ( alpha )
|
if ( alpha )
|
||||||
{
|
{
|
||||||
for ( int x = 0; x < w; x++ )
|
switch ( pf )
|
||||||
{
|
{
|
||||||
// RGB order is reversed, and we need to premultiply
|
case PixelFormat_PreMultiplied:
|
||||||
// all channels by alpha value for use with ::AlphaBlend.
|
// Pre-multiply pixel values so that the DIB could be used
|
||||||
const unsigned char a = *alpha++;
|
// with ::AlphaBlend().
|
||||||
*dst++ = (unsigned char)((src[2] * a + 127) / 255);
|
for ( int x = 0; x < w; x++ )
|
||||||
*dst++ = (unsigned char)((src[1] * a + 127) / 255);
|
{
|
||||||
*dst++ = (unsigned char)((src[0] * a + 127) / 255);
|
const unsigned char a = *alpha++;
|
||||||
*dst++ = a;
|
*dst++ = (unsigned char)((src[2] * a + 127) / 255);
|
||||||
src += 3;
|
*dst++ = (unsigned char)((src[1] * a + 127) / 255);
|
||||||
|
*dst++ = (unsigned char)((src[0] * a + 127) / 255);
|
||||||
|
*dst++ = a;
|
||||||
|
src += 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PixelFormat_NotPreMultiplied:
|
||||||
|
// Just copy pixel data without changing it.
|
||||||
|
for ( int x = 0; x < w; x++ )
|
||||||
|
{
|
||||||
|
*dst++ = src[2];
|
||||||
|
*dst++ = src[1];
|
||||||
|
*dst++ = src[0];
|
||||||
|
|
||||||
|
*dst++ = *alpha++;
|
||||||
|
src += 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else // no alpha channel
|
else // no alpha channel
|
||||||
{
|
{
|
||||||
for ( int x = 0; x < w; x++ )
|
for ( int x = 0; x < w; x++ )
|
||||||
{
|
{
|
||||||
// RGB order is reversed.
|
|
||||||
*dst++ = src[2];
|
*dst++ = src[2];
|
||||||
*dst++ = src[1];
|
*dst++ = src[1];
|
||||||
*dst++ = src[0];
|
*dst++ = src[0];
|
||||||
|
Reference in New Issue
Block a user