Fix wxBitmap::GetRawData() in wxQt

This method used to return a dangling pointer to a temporary buffer,
which resulted in a crash when using it, e.g. in the unit test.

Fix this by keeping a QImage as a member in wxBitmapRefData, so that the
pointer to its data remain valid until UngetRawData() is called.

Also check that GetRawData() returns a non-null pointer in the test.

Closes https://github.com/wxWidgets/wxWidgets/pull/1067
This commit is contained in:
Graham Dawes
2018-12-12 09:03:10 +00:00
committed by Vadim Zeitlin
parent 013c6a6b6a
commit db15e99884
2 changed files with 16 additions and 10 deletions

View File

@@ -144,6 +144,7 @@ class wxBitmapRefData: public wxGDIRefData
virtual ~wxBitmapRefData() { delete m_mask; }
QPixmap m_qtPixmap;
QImage m_rawPixelSource;
wxMask *m_mask;
private:
@@ -409,17 +410,19 @@ void wxBitmap::SetDepth(int depth)
void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
{
void* bits = NULL;
// allow access if bpp is valid and matches existence of alpha
if ( !M_PIXDATA.isNull() )
wxBitmapRefData *refData = static_cast<wxBitmapRefData *>(m_refData);
// allow access if bpp is valid
if ( !refData->m_qtPixmap.isNull() )
{
QImage qimage = M_PIXDATA.toImage();
bool hasAlpha = M_PIXDATA.hasAlphaChannel();
if ((bpp == 24 && !hasAlpha) || (bpp == 32 && hasAlpha))
if ( bpp == 32 )
{
data.m_height = qimage.height();
data.m_width = qimage.width();
data.m_stride = qimage.bytesPerLine();
bits = (void*) qimage.bits();
refData->m_rawPixelSource = refData->m_qtPixmap.toImage().convertToFormat(QImage::Format_RGBA8888);
data.m_height = refData->m_rawPixelSource.height();
data.m_width = refData->m_rawPixelSource.width();
data.m_stride = refData->m_rawPixelSource.bytesPerLine();
bits = refData->m_rawPixelSource.bits();
}
}
return bits;
@@ -427,7 +430,9 @@ void *wxBitmap::GetRawData(wxPixelDataBase& data, int bpp)
void wxBitmap::UngetRawData(wxPixelDataBase& WXUNUSED(data))
{
wxMISSING_IMPLEMENTATION( __FUNCTION__ );
wxBitmapRefData *refData = static_cast<wxBitmapRefData *>(m_refData);
refData->m_qtPixmap = QPixmap::fromImage(refData->m_rawPixelSource);
refData->m_rawPixelSource = QImage();
}
QPixmap *wxBitmap::GetHandle() const

View File

@@ -126,6 +126,7 @@ void BitmapTestCase::OverlappingBlit()
if ( m_bmp.GetDepth() == 32 )
{
wxAlphaPixelData npd( m_bmp );
CPPUNIT_ASSERT_MESSAGE( "Expected raw pixels to not be NULL", npd );
wxAlphaPixelData::Iterator it( npd );
ASSERT_EQUAL_RGB( it, 255, 0, 0 );