diff options
author | Jan-Marek Glogowski <glogow@fbihome.de> | 2018-07-05 17:45:14 +0200 |
---|---|---|
committer | Jan-Marek Glogowski <glogow@fbihome.de> | 2018-07-06 10:47:32 +0200 |
commit | ef46981023becba0f34a235a3571028dd0ea8838 (patch) | |
tree | 862c69c767e2bf86430b2a8d2458b4dcf9459e1b /vcl/qt5 | |
parent | ebd1d973eac7ef6f330634a2d2a8ca1bf3c6720e (diff) |
Qt5 implement 4bit => 32bit bitmap conversion
Some of the PNG icons are 4bit palette based PNG images.
This implements the conversation function for the most
common 4bit case, so we don't rely on some generic handling.
All other non-4bit conversions can be handled by Qt.
Change-Id: I4ddd744fb7166fc3a6992b6be6c250c2adb99ca5
Diffstat (limited to 'vcl/qt5')
-rw-r--r-- | vcl/qt5/Qt5Bitmap.cxx | 72 | ||||
-rw-r--r-- | vcl/qt5/Qt5Graphics_GDI.cxx | 22 |
2 files changed, 83 insertions, 11 deletions
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); } |