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 | |
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
-rw-r--r-- | vcl/inc/qt5/Qt5Bitmap.hxx | 2 | ||||
-rw-r--r-- | vcl/qt5/Qt5Bitmap.cxx | 72 | ||||
-rw-r--r-- | vcl/qt5/Qt5Graphics_GDI.cxx | 22 |
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); } |