summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vcl/inc/qt5/Qt5Bitmap.hxx2
-rw-r--r--vcl/qt5/Qt5Bitmap.cxx72
-rw-r--r--vcl/qt5/Qt5Graphics_GDI.cxx22
3 files changed, 84 insertions, 12 deletions
diff --git a/vcl/inc/qt5/Qt5Bitmap.hxx b/vcl/inc/qt5/Qt5Bitmap.hxx
index 6ecdebed5ca1..c89038a28fb7 100644
--- a/vcl/inc/qt5/Qt5Bitmap.hxx
+++ b/vcl/inc/qt5/Qt5Bitmap.hxx
@@ -31,7 +31,7 @@ class VCL_DLLPUBLIC Qt5Bitmap : public SalBitmap
BitmapPalette m_aPalette;
// for 4bit support
- std::unique_ptr<sal_uInt8> m_pBuffer;
+ std::unique_ptr<sal_uInt8[]> m_pBuffer;
Size m_aSize;
sal_uInt32 m_nScanline;
diff --git a/vcl/qt5/Qt5Bitmap.cxx b/vcl/qt5/Qt5Bitmap.cxx
index ff44143a16f2..824bfc28b89a 100644
--- a/vcl/qt5/Qt5Bitmap.cxx
+++ b/vcl/qt5/Qt5Bitmap.cxx
@@ -48,8 +48,17 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
{
m_pImage.reset();
m_aSize = rSize;
- m_nScanline = rSize.Width() / 2 + (rSize.Width() % 2) ? 0 : 1;
- m_pBuffer.reset(new sal_uInt8[m_nScanline * rSize.Height()]);
+ bool bFail = o3tl::checked_multiply<sal_uInt32>(rSize.Width(), nBitCount, m_nScanline);
+ if (bFail)
+ {
+ SAL_WARN("vcl.gdi", "checked multiply failed");
+ return false;
+ }
+ m_nScanline = AlignedWidth4Bytes(m_nScanline);
+ sal_uInt8* pBuffer = nullptr;
+ if (0 != m_nScanline && 0 != rSize.Height())
+ pBuffer = new sal_uInt8[m_nScanline * rSize.Height()];
+ m_pBuffer.reset(pBuffer);
}
else
{
@@ -59,7 +68,7 @@ bool Qt5Bitmap::Create(const Size& rSize, sal_uInt16 nBitCount, const BitmapPale
m_aPalette = rPal;
auto count = rPal.GetEntryCount();
- if (nBitCount != 4 && count)
+ if (nBitCount != 4 && count && m_pImage.get())
{
QVector<QRgb> aColorTable(count);
for (unsigned i = 0; i < count; ++i)
@@ -81,8 +90,14 @@ bool Qt5Bitmap::Create(const SalBitmap& rSalBmp)
{
m_aSize = pBitmap->m_aSize;
m_nScanline = pBitmap->m_nScanline;
- m_pBuffer.reset(new sal_uInt8[m_nScanline * m_aSize.Height()]);
- memcpy(m_pBuffer.get(), pBitmap->m_pBuffer.get(), m_nScanline);
+ sal_uInt8* pBuffer = nullptr;
+ if (0 != m_nScanline && 0 != m_aSize.Height())
+ {
+ sal_uInt32 nSize = m_nScanline * m_aSize.Height();
+ pBuffer = new sal_uInt8[nSize];
+ memcpy(pBuffer, pBitmap->m_pBuffer.get(), nSize);
+ }
+ m_pBuffer.reset(pBuffer);
m_pImage.reset();
}
m_aPalette = pBitmap->m_aPalette;
@@ -107,9 +122,52 @@ bool Qt5Bitmap::Create(const SalBitmap& rSalBmp, sal_uInt16 nNewBitCount)
const Qt5Bitmap* pBitmap = static_cast<const Qt5Bitmap*>(&rSalBmp);
if (pBitmap->m_pBuffer.get())
- return false;
+ {
+ if (nNewBitCount != 32)
+ return false;
+
+ // convert 4bit indexed palette to 32bit ARGB
+ m_pImage.reset(new QImage(pBitmap->m_aSize.Width(), pBitmap->m_aSize.Height(),
+ getBitFormat(nNewBitCount)));
+ m_pImage->fill(0);
+
+ // prepare a whole palette
+ const BitmapPalette& rPal = pBitmap->m_aPalette;
+ QVector<QRgb> colorTable(16);
+ int i = 0, maxEntry = pBitmap->m_aPalette.GetEntryCount();
+ assert(maxEntry <= 16 && maxEntry >= 0);
+ for (; i < maxEntry; ++i)
+ colorTable[i] = qRgb(rPal[i].GetRed(), rPal[i].GetGreen(), rPal[i].GetBlue());
+ for (; i < 16; ++i)
+ colorTable[i] = qRgb(0, 0, 0);
- m_pImage.reset(new QImage(pBitmap->m_pImage->convertToFormat(getBitFormat(nNewBitCount))));
+ sal_uInt32* image_data = reinterpret_cast<sal_uInt32*>(m_pImage->bits());
+ sal_uInt8* buffer_data_pos = pBitmap->m_pBuffer.get();
+ sal_uInt32 nWidth = pBitmap->m_aSize.Height() / 2;
+ bool isOdd(0 != pBitmap->m_aSize.Height() % 2);
+
+ for (sal_uInt32 h = 0; h < pBitmap->m_aSize.Height(); ++h)
+ {
+ sal_uInt8* buffer_data = buffer_data_pos;
+ buffer_data_pos += pBitmap->m_nScanline;
+ for (sal_uInt32 w = 0; w < nWidth; ++w)
+ {
+ *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data >> 4));
+ ++image_data;
+ *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data & 0xF));
+ ++image_data;
+ ++buffer_data;
+ }
+ if (isOdd)
+ {
+ *image_data = reinterpret_cast<sal_uInt32>(colorTable.at(*buffer_data >> 4));
+ ++image_data;
+ }
+ }
+ }
+ else
+ m_pImage.reset(new QImage(pBitmap->m_pImage->convertToFormat(getBitFormat(nNewBitCount))));
+ m_pBuffer.reset();
return true;
}
diff --git a/vcl/qt5/Qt5Graphics_GDI.cxx b/vcl/qt5/Qt5Graphics_GDI.cxx
index b58f18e4b59b..971b85f705fe 100644
--- a/vcl/qt5/Qt5Graphics_GDI.cxx
+++ b/vcl/qt5/Qt5Graphics_GDI.cxx
@@ -403,8 +403,12 @@ void Qt5Graphics::drawBitmap(const SalTwoRect& rPosAry, const SalBitmap& rSalBit
assert(rPosAry.mnSrcHeight == rPosAry.mnDestHeight);
Qt5Painter aPainter(*this);
-
- const QImage* pImage = static_cast<const Qt5Bitmap*>(&rSalBitmap)->GetQImage();
+ Qt5Bitmap aRGBABitmap;
+ if (rSalBitmap.GetBitCount() == 4)
+ aRGBABitmap.Create(rSalBitmap, 32);
+ const QImage* pImage = (rSalBitmap.GetBitCount() != 4)
+ ? static_cast<const Qt5Bitmap*>(&rSalBitmap)->GetQImage()
+ : aRGBABitmap.GetQImage();
assert(pImage);
aPainter.drawImage(
@@ -475,7 +479,12 @@ static bool getAlphaImage(const SalBitmap& rSourceBitmap, const SalBitmap& rAlph
return false;
}
- const QImage* pBitmap = static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage();
+ Qt5Bitmap aRGBABitmap;
+ if (rSourceBitmap.GetBitCount() == 4)
+ aRGBABitmap.Create(rSourceBitmap, 32);
+ const QImage* pBitmap = (rSourceBitmap.GetBitCount() != 4)
+ ? static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage()
+ : aRGBABitmap.GetQImage();
const QImage* pAlpha = static_cast<const Qt5Bitmap*>(&rAlphaBitmap)->GetQImage();
rAlphaImage = pBitmap->convertToFormat(Qt5_DefaultFormat32);
@@ -532,7 +541,12 @@ bool Qt5Graphics::drawTransformedBitmap(const basegfx::B2DPoint& rNull, const ba
return false;
else
{
- const QImage* pBitmap = static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage();
+ Qt5Bitmap aRGBABitmap;
+ if (rSourceBitmap.GetBitCount() == 4)
+ aRGBABitmap.Create(rSourceBitmap, 32);
+ const QImage* pBitmap = (rSourceBitmap.GetBitCount() != 4)
+ ? static_cast<const Qt5Bitmap*>(&rSourceBitmap)->GetQImage()
+ : aRGBABitmap.GetQImage();
aImage = pBitmap->convertToFormat(Qt5_DefaultFormat32);
}