include/vcl/canvastools.hxx | 8 + vcl/inc/canvasbitmap.hxx | 13 - vcl/qa/cppunit/canvasbitmaptest.cxx | 112 +++++++-------- vcl/source/helper/canvasbitmap.cxx | 258 +++++++++++------------------------- vcl/source/helper/canvastools.cxx | 110 ++++++--------- 5 files changed, 191 insertions(+), 310 deletions(-)
New commits: commit 2939f4b52d96ef0bd76896dc857f43d4de402d25 Author: Noel Grandin <noel.gran...@collabora.co.uk> AuthorDate: Tue Aug 5 08:26:05 2025 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Tue Aug 5 12:11:50 2025 +0200 BitmapEx->Bitmap in CanvasBitmap which reveals that the 32-bit code in CanvasBitmap is pretty broken. Change-Id: Ic575ac07b844ef591dae64259e29c25db985efeb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188932 Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> Tested-by: Jenkins diff --git a/include/vcl/canvastools.hxx b/include/vcl/canvastools.hxx index 778a092261a1..587283ebc58b 100644 --- a/include/vcl/canvastools.hxx +++ b/include/vcl/canvastools.hxx @@ -30,6 +30,7 @@ class Point; class Size; namespace tools { class Rectangle; } +class Bitmap; class BitmapEx; class Color; @@ -68,10 +69,17 @@ namespace vcl::unotools */ css::uno::Reference< css::rendering::XBitmap > VCL_DLLPUBLIC xBitmapFromBitmapEx( const ::BitmapEx& inputBitmap ); + /** Create an XBitmap from VCL Bitmap( + */ + css::uno::Reference< css::rendering::XBitmap > + VCL_DLLPUBLIC xBitmapFromBitmap( const ::Bitmap& inputBitmap ); /** Create a BitmapEx from an XBitmap */ ::BitmapEx VCL_DLLPUBLIC bitmapExFromXBitmap( const css::uno::Reference< css::rendering::XIntegerReadOnlyBitmap >& xInputBitmap ); + /** Create a Bitmap from an XBitmap + */ + ::Bitmap VCL_DLLPUBLIC bitmapFromXBitmap( const css::uno::Reference< css::rendering::XIntegerReadOnlyBitmap >& xInputBitmap ); // Color conversions (vcl/tools Color <-> canvas standard color space) diff --git a/vcl/inc/canvasbitmap.hxx b/vcl/inc/canvasbitmap.hxx index 3c76cbf984f6..1e337d829284 100644 --- a/vcl/inc/canvasbitmap.hxx +++ b/vcl/inc/canvasbitmap.hxx @@ -35,13 +35,9 @@ namespace vcl::unotools css::rendering::XIntegerBitmapColorSpace > { private: - BitmapEx m_aBmpEx; - ::Bitmap m_aBitmap; - ::Bitmap m_aAlpha; + ::Bitmap m_aBmp; BitmapScopedInfoAccess m_pBmpAcc; - BitmapScopedInfoAccess m_pAlphaAcc; std::optional<BitmapScopedReadAccess> m_pBmpReadAcc; - std::optional<BitmapScopedReadAccess> m_pAlphaReadAcc; css::uno::Sequence<sal_Int8> m_aComponentTags; css::uno::Sequence<sal_Int32> m_aComponentBitCounts; css::rendering::IntegerBitmapLayout m_aLayout; @@ -56,7 +52,6 @@ namespace vcl::unotools void setComponentInfo( sal_uInt32 redShift, sal_uInt32 greenShift, sal_uInt32 blueShift ); BitmapScopedReadAccess& getBitmapReadAccess(); - BitmapScopedReadAccess& getAlphaReadAccess(); virtual ~VclCanvasBitmap() override; @@ -103,16 +98,16 @@ namespace vcl::unotools VCL_DLLPUBLIC virtual css::uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const css::uno::Sequence< css::rendering::ARGBColor >& rgbColor ) override; virtual css::uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const css::uno::Sequence< css::rendering::ARGBColor >& rgbColor ) override; - /** Create API wrapper for given BitmapEx + /** Create API wrapper for given Bitmap @param rBitmap Bitmap to wrap. As usual, changes to the original bitmap are not reflected in this object (copy on write). */ - VCL_DLLPUBLIC explicit VclCanvasBitmap( const BitmapEx& rBitmap ); + VCL_DLLPUBLIC explicit VclCanvasBitmap( const Bitmap& rBitmap ); /// Retrieve contained bitmap. Call me with locked Solar mutex! - const BitmapEx& getBitmapEx() const { return m_aBmpEx; } + const Bitmap& getBitmap() const { return m_aBmp; } }; } diff --git a/vcl/qa/cppunit/canvasbitmaptest.cxx b/vcl/qa/cppunit/canvasbitmaptest.cxx index e562824955bd..0ece9b983fcd 100644 --- a/vcl/qa/cppunit/canvasbitmaptest.cxx +++ b/vcl/qa/cppunit/canvasbitmaptest.cxx @@ -81,14 +81,13 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, { SAL_INFO("vcl", "Testing " << msg << ", with depth " << nOriginalDepth); - BitmapEx aContainedBmpEx( xBmp->getBitmapEx() ); - Bitmap aContainedBmp( aContainedBmpEx.GetBitmap() ); - int nDepth = nOriginalDepth; - int extraBpp = 0; - + Bitmap aContainedBmp( xBmp->getBitmap() ); + int nDepth; + bool bHasPalette; { BitmapScopedReadAccess pAcc( aContainedBmp ); nDepth = pAcc->GetBitCount(); + bHasPalette = pAcc->HasPalette(); } CPPUNIT_ASSERT_EQUAL_MESSAGE( "Original bitmap size not (200,200)", @@ -100,7 +99,7 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, sal_Int32(200), xBmp->getSize().Height); CPPUNIT_ASSERT_EQUAL_MESSAGE( "alpha state mismatch", - aContainedBmpEx.IsAlpha(), bool(xBmp->hasAlpha())); + aContainedBmp.HasAlpha(), bool(xBmp->hasAlpha())); CPPUNIT_ASSERT_MESSAGE( "getScaledBitmap() failed", xBmp->getScaledBitmap( geometry::RealSize2D(500,500), false ).is()); @@ -108,8 +107,7 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, rendering::IntegerBitmapLayout aLayout; uno::Sequence<sal_Int8> aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,1,1)); - const sal_Int32 nExpectedBitsPerPixel( - (aContainedBmpEx.IsAlpha() ? std::max(8,nDepth)+8 : nDepth) + extraBpp); + const sal_Int32 nExpectedBitsPerPixel(bHasPalette ? 8 : (aContainedBmp.HasAlpha() ? 32 : 24)); CPPUNIT_ASSERT_EQUAL_MESSAGE( "# scanlines not 1", static_cast<sal_Int32>(1), aLayout.ScanLines); CPPUNIT_ASSERT_EQUAL_MESSAGE( "# scanline bytes mismatch", @@ -131,7 +129,7 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, CPPUNIT_ASSERT_EQUAL_MESSAGE( "getData and getPixel did not return same amount of data", aPixelData.getLength(), aPixelData2.getLength()); - aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,200,1)); + aPixelData = xBmp->getData(aLayout, geometry::IntegerRectangle2D(0,0,/*X2*/200,/*Y2*/1)); CPPUNIT_ASSERT_EQUAL_MESSAGE( "# scanlines not 1 for getPixel", static_cast<sal_Int32>(1), aLayout.ScanLines); CPPUNIT_ASSERT_EQUAL_MESSAGE( "# scanline bytes mismatch for getPixel", @@ -154,18 +152,30 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, CPPUNIT_ASSERT_MESSAGE( "rgb colors are not within [0,1] range", std::none_of(pRGBStart,pRGBEnd,&rangeCheck)); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "First pixel is not white", 1.0, pRGBStart[0].Red, 1E-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "First pixel is not white", 1.0, pRGBStart[0].Green, 1E-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "First pixel is not white", 1.0, pRGBStart[0].Blue, 1E-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "Second pixel is not opaque", 1.0, pARGBStart[1].Alpha, 1E-12); - if( aContainedBmpEx.IsAlpha() ) - { + if( !aContainedBmp.HasAlpha() ) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "First pixel is not white", 1.0, pRGBStart[0].Red, 1E-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "First pixel is not white", 1.0, pRGBStart[0].Green, 1E-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "First pixel is not white", 1.0, pRGBStart[0].Blue, 1E-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "Second pixel is not opaque", 1.0, pARGBStart[1].Alpha, 1E-12); + } + else + { + // with premultipled alpha, the white becomes black + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "First pixel is not black", 0.0, pRGBStart[0].Red, 1E-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "First pixel is not black", 0.0, pRGBStart[0].Green, 1E-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "First pixel is not black", 0.0, pRGBStart[0].Blue, 1E-12); CPPUNIT_ASSERT_EQUAL_MESSAGE( "First pixel is not fully transparent", 0.0, pARGBStart[0].Alpha); + CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( + "Second pixel is not opaque", 1.0, pARGBStart[1].Alpha, 1E-12); } CPPUNIT_ASSERT_EQUAL_MESSAGE( "Second pixel is not black", @@ -175,7 +185,7 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, CPPUNIT_ASSERT_EQUAL_MESSAGE( "Second pixel is not black", 0.0, pRGBStart[1].Blue); - if( nOriginalDepth > 8 ) + if( !bHasPalette ) { const Color aCol(COL_GREEN); CPPUNIT_ASSERT_EQUAL_MESSAGE( @@ -188,7 +198,7 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, "Sixth pixel is not green (blue component)", vcl::unotools::toDoubleColor(aCol.GetBlue()), pRGBStart[5].Blue); } - else if( nDepth <= 8 ) + else { uno::Reference<rendering::XBitmapPalette> xPal = xBmp->getPalette(); CPPUNIT_ASSERT_MESSAGE( "8bit or less: missing palette", @@ -204,13 +214,6 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, xPal->getColorSpace().is()); } - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "150th pixel is not white", 1.0, pRGBStart[150].Red, 1E-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "150th pixel is not white", 1.0, pRGBStart[150].Green, 1E-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE( - "150th pixel is not white", 1.0, pRGBStart[150].Blue, 1E-12); - if( nOriginalDepth <= 8 ) return; @@ -227,22 +230,21 @@ void checkCanvasBitmap( const rtl::Reference<VclCanvasBitmap>& xBmp, } }; - uno::Sequence<rendering::RGBColor> aRGBColor - { - { - vcl::unotools::toDoubleColor(aCol.GetRed()), - vcl::unotools::toDoubleColor(aCol.GetGreen()), - vcl::unotools::toDoubleColor(aCol.GetBlue()) - } - }; - aPixel3 = xBmp->convertIntegerFromARGB( aARGBColor ); aPixel4 = xBmp->getPixel( aLayout, geometry::IntegerPoint2D(5,0) ); CPPUNIT_ASSERT_MESSAGE( "Green pixel from bitmap mismatch with manually converted green pixel", bool(aPixel3 == aPixel4)); - if( !aContainedBmpEx.IsAlpha() ) + if( !aContainedBmp.HasAlpha() ) { + uno::Sequence<rendering::RGBColor> aRGBColor + { + { + vcl::unotools::toDoubleColor(aCol.GetRed()), + vcl::unotools::toDoubleColor(aCol.GetGreen()), + vcl::unotools::toDoubleColor(aCol.GetBlue()) + } + }; aPixel3 = xBmp->convertIntegerFromRGB( aRGBColor ); CPPUNIT_ASSERT_MESSAGE( "Green pixel from bitmap mismatch with manually RGB-converted green pixel", bool(aPixel3 == aPixel4)); @@ -305,7 +307,7 @@ private: pOut[ y*nScanlineLen + 4*x ] = sal_Int8(rect.X1); pOut[ y*nScanlineLen + 4*x + 1 ] = sal_Int8(rect.Y2); pOut[ y*nScanlineLen + 4*x + 2 ] = sal_Int8(x); - pOut[ y*nScanlineLen + 4*x + 3 ] = sal_Int8(rect.Y1); + pOut[ y*nScanlineLen + 4*x + 3 ] = -1; // alpha, fully opaque } } } @@ -666,7 +668,7 @@ void CanvasBitmapTest::runTest() } } - rtl::Reference<VclCanvasBitmap> xBmp( new VclCanvasBitmap(BitmapEx(aBitmap)) ); + rtl::Reference<VclCanvasBitmap> xBmp( new VclCanvasBitmap(aBitmap) ); checkCanvasBitmap( xBmp, "single bitmap", nDepth ); @@ -684,7 +686,7 @@ void CanvasBitmapTest::runTest() } } - xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aMask)) ); + xBmp.set( new VclCanvasBitmap(Bitmap(BitmapEx(aBitmap,aMask))) ); checkCanvasBitmap( xBmp, "masked bitmap", nDepth ); @@ -702,7 +704,7 @@ void CanvasBitmapTest::runTest() } } - xBmp.set( new VclCanvasBitmap(BitmapEx(aBitmap,aAlpha)) ); + xBmp.set( new VclCanvasBitmap(Bitmap(BitmapEx(aBitmap,aAlpha))) ); checkCanvasBitmap( xBmp, "alpha bitmap", nDepth ); } @@ -712,16 +714,15 @@ void CanvasBitmapTest::runTest() uno::Reference< rendering::XIntegerReadOnlyBitmap > xTestBmp( new TestBitmap( geometry::IntegerSize2D(10,10), true )); - BitmapEx aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp); + Bitmap aBmp = vcl::unotools::bitmapFromXBitmap(xTestBmp); CPPUNIT_ASSERT_MESSAGE( "Palette bitmap is alpha", - !aBmp.IsAlpha()); + !aBmp.HasAlpha()); CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bitmap does not have size (10,10)", Size(10,10), aBmp.GetSizePixel()); CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bitmap does not have the expected pixel format", vcl::PixelFormat::N8_BPP, aBmp.getPixelFormat()); { - Bitmap aBitmap = aBmp.GetBitmap(); - BitmapScopedReadAccess pBmpAcc(aBitmap); + BitmapScopedReadAccess pBmpAcc(aBmp); CPPUNIT_ASSERT_MESSAGE( "Bitmap has invalid BitmapReadAccess", pBmpAcc ); @@ -736,36 +737,25 @@ void CanvasBitmapTest::runTest() xTestBmp.set( new TestBitmap( geometry::IntegerSize2D(10,10), false )); - aBmp = vcl::unotools::bitmapExFromXBitmap(xTestBmp); + aBmp = vcl::unotools::bitmapFromXBitmap(xTestBmp); CPPUNIT_ASSERT_MESSAGE( "Palette bitmap has no alpha", - aBmp.IsAlpha()); + aBmp.HasAlpha()); CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bitmap does not have size (10,10)", Size(10,10), aBmp.GetSizePixel()); CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bitmap does not have the expected pixel format", - vcl::PixelFormat::N24_BPP, aBmp.getPixelFormat()); + vcl::PixelFormat::N32_BPP, aBmp.getPixelFormat()); { - Bitmap aBitmap = aBmp.GetBitmap(); - BitmapScopedReadAccess pBmpAcc(aBitmap); - AlphaMask aBitmapAlpha = aBmp.GetAlphaMask(); - BitmapScopedReadAccess pAlphaAcc(aBitmapAlpha); + BitmapScopedReadAccess pBmpAcc(aBmp); CPPUNIT_ASSERT_MESSAGE( "Bitmap has invalid BitmapReadAccess", pBmpAcc); - CPPUNIT_ASSERT_MESSAGE( "Bitmap has invalid alpha BitmapReadAccess", - pAlphaAcc); CPPUNIT_ASSERT_EQUAL_MESSAGE("(0,0) incorrect content", BitmapColor(0,1,0), pBmpAcc->GetPixel(0,0)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("(0,0) incorrect alpha content", - BitmapColor(0), pAlphaAcc->GetPixel(0,0)); CPPUNIT_ASSERT_EQUAL_MESSAGE("(2,2) incorrect content", BitmapColor(0,3,2), pBmpAcc->GetPixel(2,2)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("(2,2) incorrect alpha content", - BitmapColor(2), pAlphaAcc->GetPixel(2,2)); CPPUNIT_ASSERT_EQUAL_MESSAGE("(9,2) incorrect content", BitmapColor(0,3,9), pBmpAcc->GetPixel(2,9)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("(9,2) correct alpha content", - BitmapColor(2), pAlphaAcc->GetPixel(2,9)); } } diff --git a/vcl/source/helper/canvasbitmap.cxx b/vcl/source/helper/canvasbitmap.cxx index e2bd7b1b8f80..f363f8aa1e3c 100644 --- a/vcl/source/helper/canvasbitmap.cxx +++ b/vcl/source/helper/canvasbitmap.cxx @@ -101,21 +101,13 @@ BitmapScopedReadAccess& VclCanvasBitmap::getBitmapReadAccess() // from the system format (and even fetched). Most calls here // need only info access, create read access only on demand. if(!m_pBmpReadAcc) - m_pBmpReadAcc.emplace(m_aBitmap); + m_pBmpReadAcc.emplace(m_aBmp); return *m_pBmpReadAcc; } -BitmapScopedReadAccess& VclCanvasBitmap::getAlphaReadAccess() -{ - if(!m_pAlphaReadAcc) - m_pAlphaReadAcc.emplace(m_aAlpha); - return *m_pAlphaReadAcc; -} - -VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : - m_aBmpEx( rBitmap ), - m_aBitmap( rBitmap.GetBitmap() ), - m_pBmpAcc( m_aBitmap ), +VclCanvasBitmap::VclCanvasBitmap( const Bitmap& rBitmap ) : + m_aBmp( rBitmap ), + m_pBmpAcc( m_aBmp ), m_nBitsPerInputPixel(0), m_nBitsPerOutputPixel(0), m_nRedIndex(-1), @@ -125,12 +117,6 @@ VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : m_nIndexIndex(-1), m_bPalette(false) { - if( m_aBmpEx.IsAlpha() ) - { - m_aAlpha = m_aBmpEx.GetAlphaMask().GetBitmap(); - m_pAlphaAcc = m_aAlpha; - } - m_aLayout.ScanLines = 0; m_aLayout.ScanLineBytes = 0; m_aLayout.ScanLineStride = 0; @@ -183,7 +169,7 @@ VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : case ScanlineFormat::N32BitTcXbgr: { m_bPalette = false; - m_nBitsPerInputPixel = 32; + m_nBitsPerInputPixel = 24; m_aLayout.IsMsbFirst = false; // doesn't matter m_aComponentTags = { /* 0 */ rendering::ColorComponentTag::ALPHA, @@ -207,7 +193,7 @@ VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : case ScanlineFormat::N32BitTcXrgb: { m_bPalette = false; - m_nBitsPerInputPixel = 32; + m_nBitsPerInputPixel = 24; m_aLayout.IsMsbFirst = false; // doesn't matter m_aComponentTags = { /* 0 */ rendering::ColorComponentTag::ALPHA, @@ -231,7 +217,7 @@ VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : case ScanlineFormat::N32BitTcBgrx: { m_bPalette = false; - m_nBitsPerInputPixel = 32; + m_nBitsPerInputPixel = 24; m_aLayout.IsMsbFirst = false; // doesn't matter m_aComponentTags = { /* 0 */ rendering::ColorComponentTag::RGB_BLUE, @@ -255,7 +241,7 @@ VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : case ScanlineFormat::N32BitTcRgbx: { m_bPalette = false; - m_nBitsPerInputPixel = 32; + m_nBitsPerInputPixel = 24; m_aLayout.IsMsbFirst = false; // doesn't matter m_aComponentTags = { /* 0 */ rendering::ColorComponentTag::RGB_RED, @@ -290,7 +276,7 @@ VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : } m_nBitsPerOutputPixel = m_nBitsPerInputPixel; - if( !m_aBmpEx.IsAlpha() ) + if( !m_aBmp.HasAlpha() ) return; // TODO(P1): need to interleave alpha with bitmap data - @@ -310,14 +296,14 @@ VclCanvasBitmap::VclCanvasBitmap( const BitmapEx& rBitmap ) : m_aComponentTags.getArray()[m_aComponentTags.getLength()-1] = rendering::ColorComponentTag::ALPHA; m_aComponentBitCounts.realloc(m_aComponentBitCounts.getLength()+1); - m_aComponentBitCounts.getArray()[m_aComponentBitCounts.getLength()-1] = m_aBmpEx.IsAlpha() ? 8 : 1; + m_aComponentBitCounts.getArray()[m_aComponentBitCounts.getLength()-1] = m_aBmp.HasAlpha() ? 8 : 1; // always add a full byte to the pixel size, otherwise // pixel packing hell breaks loose. m_nBitsPerOutputPixel += 8; // adapt scanline parameters - const Size aSize = m_aBitmap.GetSizePixel(); + const Size aSize = m_aBmp.GetSizePixel(); m_aLayout.ScanLineBytes = m_aLayout.ScanLineStride = (aSize.Width()*m_nBitsPerOutputPixel + 7)/8; } @@ -330,13 +316,13 @@ VclCanvasBitmap::~VclCanvasBitmap() geometry::IntegerSize2D SAL_CALL VclCanvasBitmap::getSize() { SolarMutexGuard aGuard; - return integerSize2DFromSize( m_aBitmap.GetSizePixel() ); + return integerSize2DFromSize( m_aBmp.GetSizePixel() ); } sal_Bool SAL_CALL VclCanvasBitmap::hasAlpha() { SolarMutexGuard aGuard; - return m_aBmpEx.IsAlpha(); + return m_aBmp.HasAlpha(); } uno::Reference< rendering::XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( const geometry::RealSize2D& newSize, @@ -344,7 +330,7 @@ uno::Reference< rendering::XBitmap > SAL_CALL VclCanvasBitmap::getScaledBitmap( { SolarMutexGuard aGuard; - BitmapEx aNewBmp( m_aBitmap ); + Bitmap aNewBmp( m_aBmp ); aNewBmp.Scale( sizeFromRealSize2D( newSize ), beFast ? BmpScaleFlag::Default : BmpScaleFlag::BestQuality ); return uno::Reference<rendering::XBitmap>( new VclCanvasBitmap( aNewBmp ) ); } @@ -364,8 +350,6 @@ uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerB // Invalid/empty bitmap: no data available if( !m_pBmpAcc ) throw lang::IndexOutOfBoundsException(); - if( m_aBmpEx.IsAlpha() && !m_pAlphaAcc ) - throw lang::IndexOutOfBoundsException(); if( aRequestedArea.Left() < 0 || aRequestedArea.Top() < 0 || aRequestedArea.Right() > m_pBmpAcc->Width() || @@ -396,7 +380,7 @@ uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerB nScanlineStride *= -1; } - if( !m_aBmpEx.IsAlpha() ) + if( !m_aBmp.HasAlpha() ) { BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); OSL_ENSURE(pBmpAcc,"Invalid bmp read access"); @@ -411,47 +395,30 @@ uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getData( rendering::IntegerB } else { - BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); - BitmapScopedReadAccess& pAlphaAcc = getAlphaReadAccess(); - OSL_ENSURE(pBmpAcc,"Invalid bmp read access"); - OSL_ENSURE(pAlphaAcc,"Invalid alpha read access"); + assert( m_nBitsPerInputPixel == 24 ); + assert( m_nBitsPerOutputPixel == 32 ); - // interleave alpha with bitmap data - note, bitcount is - // always integer multiple of 8 - OSL_ENSURE((m_nBitsPerOutputPixel & 0x07) == 0, - "Transparent bitmap bitcount not integer multiple of 8" ); + BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); + assert(pBmpAcc && "Invalid bmp read access"); for( tools::Long y=aRequestedArea.Top(); y<aRequestedArea.Bottom(); ++y ) { sal_Int8* pOutScan = pOutBuf; - if( m_nBitsPerInputPixel < 8 ) - { - // input less than a byte - copy via GetPixel() - for( tools::Long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x ) - { - *pOutScan++ = pBmpAcc->GetPixelIndex(y,x); - // vcl used to store transparency. Now it stores alpha. But we need the UNO - // interface to still preserve the old interface. - *pOutScan++ = 255 - pAlphaAcc->GetPixelIndex(y,x); - } - } - else + const tools::Long nScanlineOffsetLeft(aRequestedArea.Left()*m_nBitsPerOutputPixel/8); + Scanline pScan = pBmpAcc->GetScanline(y) + nScanlineOffsetLeft; + + for( tools::Long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x ) { - const tools::Long nNonAlphaBytes( m_nBitsPerInputPixel/8 ); - const tools::Long nScanlineOffsetLeft(aRequestedArea.Left()*nNonAlphaBytes); - Scanline pScan = pBmpAcc->GetScanline(y) + nScanlineOffsetLeft; - Scanline pScanlineAlpha = pAlphaAcc->GetScanline( y ); - - // input integer multiple of byte - copy directly - for( tools::Long x=aRequestedArea.Left(); x<aRequestedArea.Right(); ++x ) - { - for( tools::Long i=0; i<nNonAlphaBytes; ++i ) - *pOutScan++ = *pScan++; - // vcl used to store transparency. Now it stores alpha. But we need the UNO - // interface to still preserve the old interface. - *pOutScan++ = 255 - pAlphaAcc->GetIndexFromData( pScanlineAlpha, x ); - } + // return it always in the same format. This makes the conversion + // in the convertIntegerTo* methods easier. + BitmapColor aCol = pBmpAcc->GetPixelFromData(pScan, x); + *pOutScan++ = aCol.GetBlue(); + *pOutScan++ = aCol.GetGreen(); + *pOutScan++ = aCol.GetRed(); + // vcl used to store transparency. Now it stores alpha. But we need the UNO + // interface to still preserve the old interface. + *pOutScan++ = 255 - aCol.GetAlpha(); } pOutBuf += nScanlineStride; @@ -471,8 +438,6 @@ uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( rendering::Integer // Invalid/empty bitmap: no data available if( !m_pBmpAcc ) throw lang::IndexOutOfBoundsException(); - if( m_aBmpEx.IsAlpha() && !m_pAlphaAcc ) - throw lang::IndexOutOfBoundsException(); if( pos.X < 0 || pos.Y < 0 || pos.X > m_pBmpAcc->Width() || pos.Y > m_pBmpAcc->Height() ) @@ -488,48 +453,30 @@ uno::Sequence< sal_Int8 > SAL_CALL VclCanvasBitmap::getPixel( rendering::Integer bitmapLayout.ScanLineBytes = bitmapLayout.ScanLineStride= aRet.getLength(); - const tools::Long nScanlineLeftOffset( pos.X*m_nBitsPerInputPixel/8 ); - if( !m_aBmpEx.IsAlpha() ) - { - BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); - assert(pBmpAcc && "Invalid bmp read access"); + BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); + assert(pBmpAcc && "Invalid bmp read access"); + if( !m_aBmp.HasAlpha() ) + { // can return bitmap data as-is Scanline pScan = pBmpAcc->GetScanline(pos.Y); + const tools::Long nScanlineLeftOffset( pos.X*m_nBitsPerOutputPixel/8 ); memcpy(pOutBuf, pScan+nScanlineLeftOffset, aRet.getLength() ); } else { - BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); - BitmapScopedReadAccess& pAlphaAcc = getAlphaReadAccess(); - assert(pBmpAcc && "Invalid bmp read access"); - assert(pAlphaAcc && "Invalid alpha read access"); - - // interleave alpha with bitmap data - note, bitcount is - // always integer multiple of 8 - assert((m_nBitsPerOutputPixel & 0x07) == 0 && - "Transparent bitmap bitcount not integer multiple of 8" ); - - if( m_nBitsPerInputPixel < 8 ) - { - // input less than a byte - copy via GetPixel() - *pOutBuf++ = pBmpAcc->GetPixelIndex(pos.Y,pos.X); - // vcl used to store transparency. Now it stores alpha. But we need the UNO - // interface to still preserve the old interface. - *pOutBuf = 255 - pAlphaAcc->GetPixelIndex(pos.Y,pos.X); - } - else - { - const tools::Long nNonAlphaBytes( m_nBitsPerInputPixel/8 ); - Scanline pScan = pBmpAcc->GetScanline(pos.Y); - - // input integer multiple of byte - copy directly - memcpy(pOutBuf, pScan+nScanlineLeftOffset, nNonAlphaBytes ); - pOutBuf += nNonAlphaBytes; - // vcl used to store transparency. Now it stores alpha. But we need the UNO - // interface to still preserve the old interface. - *pOutBuf++ = 255 - pAlphaAcc->GetPixelIndex(pos.Y,pos.X); - } + assert( m_nBitsPerInputPixel == 24 ); + assert( m_nBitsPerOutputPixel == 32 ); + + // return it always in the same format. This makes the conversion + // in the convertIntegerTo* methods easier. + BitmapColor aCol = pBmpAcc->GetPixel(pos.Y, pos.X); + *pOutBuf++ = aCol.GetBlue(); + *pOutBuf++ = aCol.GetGreen(); + *pOutBuf++ = aCol.GetRed(); + // vcl used to store transparency. Now it stores alpha. But we need the UNO + // interface to still preserve the old interface. + *pOutBuf++ = 255 - aCol.GetAlpha(); } return aRet; @@ -1037,21 +984,16 @@ uno::Sequence<rendering::RGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToRGB ENSURE_OR_THROW(pBmpAcc, "Unable to get BitmapAccess"); - if( m_aBmpEx.IsAlpha() ) + if( m_aBmp.HasAlpha() ) { + assert(!m_bPalette && "alpha bitmaps never have palette"); const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8); for( std::size_t i=0; i<nLen; i+=nBytesPerPixel ) { - // if palette, index is guaranteed to be 8 bit - const BitmapColor aCol = - m_bPalette ? - pBmpAcc->GetPaletteColor(*pIn) : - pBmpAcc->GetPixelFromData(pIn,0); - // TODO(F3): Convert result to sRGB color space - *pOut++ = rendering::RGBColor(toDoubleColor(aCol.GetRed()), - toDoubleColor(aCol.GetGreen()), - toDoubleColor(aCol.GetBlue())); + *pOut++ = rendering::RGBColor(toDoubleColor(pIn[2]), + toDoubleColor(pIn[1]), + toDoubleColor(pIn[0])); // skips alpha pIn += nBytesPerPixel; } @@ -1090,23 +1032,17 @@ uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToAR ENSURE_OR_THROW(pBmpAcc, "Unable to get BitmapAccess"); - if( m_aBmpEx.IsAlpha() ) + if( m_aBmp.HasAlpha() ) { - const tools::Long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 ); + assert(!m_bPalette && "alpha bitmaps never have palette"); const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8); for( std::size_t i=0; i<nLen; i+=nBytesPerPixel ) { - // if palette, index is guaranteed to be 8 bit - const BitmapColor aCol = - m_bPalette ? - pBmpAcc->GetPaletteColor(*pIn) : - pBmpAcc->GetPixelFromData(pIn,0); - // TODO(F3): Convert result to sRGB color space - *pOut++ = rendering::ARGBColor(1.0 - toDoubleColor(pIn[nNonAlphaBytes]), - toDoubleColor(aCol.GetRed()), - toDoubleColor(aCol.GetGreen()), - toDoubleColor(aCol.GetBlue())); + *pOut++ = rendering::ARGBColor(1.0 - toDoubleColor(pIn[3]), + toDoubleColor(pIn[2]), + toDoubleColor(pIn[1]), + toDoubleColor(pIn[0])); pIn += nBytesPerPixel; } } @@ -1145,24 +1081,18 @@ uno::Sequence<rendering::ARGBColor> SAL_CALL VclCanvasBitmap::convertIntegerToPA ENSURE_OR_THROW(pBmpAcc, "Unable to get BitmapAccess"); - if( m_aBmpEx.IsAlpha() ) + if( m_aBmp.HasAlpha() ) { - const tools::Long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 ); + assert(!m_bPalette && "alpha bitmaps never have palette"); const sal_Int32 nBytesPerPixel((m_nBitsPerOutputPixel+7)/8); for( std::size_t i=0; i<nLen; i+=nBytesPerPixel ) { - // if palette, index is guaranteed to be 8 bit - const BitmapColor aCol = - m_bPalette ? - pBmpAcc->GetPaletteColor(*pIn) : - pBmpAcc->GetPixelFromData(pIn,0); - // TODO(F3): Convert result to sRGB color space - const double nAlpha( 1.0 - toDoubleColor(pIn[nNonAlphaBytes]) ); + const double nAlpha( 1.0 - toDoubleColor(pIn[3]) ); *pOut++ = rendering::ARGBColor(nAlpha, - nAlpha*toDoubleColor(aCol.GetRed()), - nAlpha*toDoubleColor(aCol.GetGreen()), - nAlpha*toDoubleColor(aCol.GetBlue())); + nAlpha*toDoubleColor(pIn[2]), + nAlpha*toDoubleColor(pIn[1]), + nAlpha*toDoubleColor(pIn[0])); pIn += nBytesPerPixel; } } @@ -1197,23 +1127,15 @@ uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromRGB( con sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray()); BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); - if( m_aBmpEx.IsAlpha() ) + if( m_aBmp.HasAlpha() ) { - const tools::Long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 ); + assert(!m_bPalette && "alpha bitmaps never have palette"); for( std::size_t i=0; i<nLen; ++i ) { - const BitmapColor aCol(toByteColor(rgbColor[i].Red), - toByteColor(rgbColor[i].Green), - toByteColor(rgbColor[i].Blue)); - const BitmapColor aCol2 = - m_bPalette ? - BitmapColor( - sal::static_int_cast<sal_uInt8>(pBmpAcc->GetBestPaletteIndex( aCol ))) : - aCol; - - pBmpAcc->SetPixelOnData(pColors,i,aCol2); - pColors += nNonAlphaBytes; - *pColors++ = sal_uInt8(255); + *pColors++ = toByteColor(rgbColor[i].Blue); + *pColors++ = toByteColor(rgbColor[i].Green); + *pColors++ = toByteColor(rgbColor[i].Red); + *pColors++ = 0; } } else @@ -1247,22 +1169,14 @@ uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromARGB( co sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray()); BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); - if( m_aBmpEx.IsAlpha() ) + if( m_aBmp.HasAlpha() ) { - const tools::Long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 ); + assert(!m_bPalette && "alpha bitmaps never have palette"); for( std::size_t i=0; i<nLen; ++i ) { - const BitmapColor aCol(toByteColor(rgbColor[i].Red), - toByteColor(rgbColor[i].Green), - toByteColor(rgbColor[i].Blue)); - const BitmapColor aCol2 = - m_bPalette ? - BitmapColor( - sal::static_int_cast<sal_uInt8>(pBmpAcc->GetBestPaletteIndex( aCol ))) : - aCol; - - pBmpAcc->SetPixelOnData(pColors,i,aCol2); - pColors += nNonAlphaBytes; + *pColors++ = toByteColor(rgbColor[i].Blue); + *pColors++ = toByteColor(rgbColor[i].Green); + *pColors++ = toByteColor(rgbColor[i].Red); *pColors++ = 255 - toByteColor(rgbColor[i].Alpha); } } @@ -1297,23 +1211,15 @@ uno::Sequence< ::sal_Int8 > SAL_CALL VclCanvasBitmap::convertIntegerFromPARGB( c sal_uInt8* pColors=reinterpret_cast<sal_uInt8*>(aRes.getArray()); BitmapScopedReadAccess& pBmpAcc = getBitmapReadAccess(); - if( m_aBmpEx.IsAlpha() ) + if( m_aBmp.HasAlpha() ) { - const tools::Long nNonAlphaBytes( (m_nBitsPerInputPixel+7)/8 ); + assert(!m_bPalette && "alpha bitmaps never have palette"); for( std::size_t i=0; i<nLen; ++i ) { const double nAlpha( rgbColor[i].Alpha ); - const BitmapColor aCol(toByteColor(rgbColor[i].Red / nAlpha), - toByteColor(rgbColor[i].Green / nAlpha), - toByteColor(rgbColor[i].Blue / nAlpha)); - const BitmapColor aCol2 = - m_bPalette ? - BitmapColor( - sal::static_int_cast<sal_uInt8>(pBmpAcc->GetBestPaletteIndex( aCol ))) : - aCol; - - pBmpAcc->SetPixelOnData(pColors,i,aCol2); - pColors += nNonAlphaBytes; + *pColors++ = toByteColor(rgbColor[i].Blue / nAlpha); + *pColors++ = toByteColor(rgbColor[i].Green / nAlpha); + *pColors++ = toByteColor(rgbColor[i].Red / nAlpha); *pColors++ = 255 - toByteColor(nAlpha); } } diff --git a/vcl/source/helper/canvastools.cxx b/vcl/source/helper/canvastools.cxx index 49dfd0e95892..7dbfbc649c1d 100644 --- a/vcl/source/helper/canvastools.cxx +++ b/vcl/source/helper/canvastools.cxx @@ -53,6 +53,13 @@ namespace vcl::unotools { SAL_INFO( "vcl.helper", "vcl::unotools::xBitmapFromBitmapEx()" ); + return new vcl::unotools::VclCanvasBitmap( Bitmap(inputBitmap) ); + } + + uno::Reference< rendering::XBitmap > xBitmapFromBitmap(const ::Bitmap& inputBitmap ) + { + SAL_INFO( "vcl.helper", "vcl::unotools::xBitmapFromBitmapEx()" ); + return new vcl::unotools::VclCanvasBitmap( inputBitmap ); } @@ -74,7 +81,7 @@ namespace vcl::unotools const rendering::IntegerBitmapLayout& rLayout, const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap, BitmapScopedWriteAccess& rWriteAcc, - BitmapScopedWriteAccess& rAlphaAcc ) + bool bHasAlpha ) { rendering::IntegerBitmapLayout aCurrLayout; geometry::IntegerRectangle2D aRect; @@ -98,38 +105,21 @@ namespace vcl::unotools return false; // re-read bmp from the start Scanline pScanline = rWriteAcc->GetScanline( aRect.Y1 ); - if( rAlphaAcc.get() ) + if( bHasAlpha ) { - Scanline pScanlineAlpha = rAlphaAcc->GetScanline( aRect.Y1 ); // read ARGB color aARGBColors = rLayout.ColorSpace->convertIntegerToARGB(aPixelData); - if( rWriteAcc->HasPalette() ) - { - for( sal_Int32 x=0; x<nWidth; ++x ) - { - const rendering::ARGBColor& rColor=aARGBColors[x]; - rWriteAcc->SetPixelOnData( pScanline, x, - BitmapColor(static_cast<sal_uInt8>(rWriteAcc->GetBestPaletteIndex( - BitmapColor( toByteColor(rColor.Red), - toByteColor(rColor.Green), - toByteColor(rColor.Blue))))) ); - rAlphaAcc->SetPixelOnData( pScanlineAlpha, x, - BitmapColor( toByteColor(rColor.Alpha) )); - } - } - else + assert( !rWriteAcc->HasPalette() ); + for( sal_Int32 x=0; x<nWidth; ++x ) { - for( sal_Int32 x=0; x<nWidth; ++x ) - { - const rendering::ARGBColor& rColor=aARGBColors[x]; - rWriteAcc->SetPixelOnData( pScanline, x, - BitmapColor( toByteColor(rColor.Red), - toByteColor(rColor.Green), - toByteColor(rColor.Blue) )); - rAlphaAcc->SetPixelOnData( pScanlineAlpha, x, - BitmapColor( toByteColor(rColor.Alpha) )); - } + const rendering::ARGBColor& rColor=aARGBColors[x]; + rWriteAcc->SetPixelOnData( pScanline, x, + BitmapColor( ColorAlpha, + toByteColor(rColor.Red), + toByteColor(rColor.Green), + toByteColor(rColor.Blue), + toByteColor(rColor.Alpha) )); } } else @@ -167,16 +157,21 @@ namespace vcl::unotools } ::BitmapEx bitmapExFromXBitmap( const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap ) + { + return BitmapEx(bitmapFromXBitmap(xInputBitmap)); + } + + ::Bitmap bitmapFromXBitmap( const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap ) { SAL_INFO( "vcl.helper", "vcl::unotools::bitmapExFromXBitmap()" ); if( !xInputBitmap.is() ) - return ::BitmapEx(); + return ::Bitmap(); // tunnel directly for known implementation VclCanvasBitmap* pImplBitmap = dynamic_cast<VclCanvasBitmap*>(xInputBitmap.get()); if( pImplBitmap ) - return pImplBitmap->getBitmapEx(); + return pImplBitmap->getBitmap(); // retrieve data via UNO interface @@ -187,14 +182,14 @@ namespace vcl::unotools for( int i=0; i<10; ++i ) { sal_Int32 nDepth=0; - sal_Int32 nAlphaDepth=0; + bool bHasAlpha = false; const rendering::IntegerBitmapLayout aLayout( xInputBitmap->getMemoryLayout()); OSL_ENSURE(aLayout.ColorSpace.is(), "Cannot convert image without color space!"); if( !aLayout.ColorSpace.is() ) - return ::BitmapEx(); + return ::Bitmap(); nDepth = aLayout.ColorSpace->getBitsPerPixel(); @@ -211,16 +206,18 @@ namespace vcl::unotools std::find(pStart,pEnd, rendering::ColorComponentTag::ALPHA) - pStart; - if( nAlphaIndex < sal::static_int_cast<std::ptrdiff_t>(nLen) ) - { - nAlphaDepth = aLayout.ColorSpace->getComponentBitCounts()[nAlphaIndex] > 1 ? 8 : 1; - nDepth -= nAlphaDepth; - } + ENSURE_OR_THROW( nAlphaIndex < sal::static_int_cast<std::ptrdiff_t>(nLen), + "bitmap has alpha, but alphaindex not valid"); + auto nAlphaBitCount = aLayout.ColorSpace->getComponentBitCounts()[nAlphaIndex]; + ENSURE_OR_THROW(nAlphaBitCount == 8, "unsupported alpha bit count"); + bHasAlpha = true; + nDepth -= nAlphaBitCount; } BitmapPalette aPalette; if( aLayout.Palette.is() ) { + ENSURE_OR_THROW(!bHasAlpha, "unsupported"); uno::Reference< rendering::XColorSpace > xPaletteColorSpace( aLayout.Palette->getColorSpace()); ENSURE_OR_THROW(xPaletteColorSpace.is(), @@ -246,11 +243,8 @@ namespace vcl::unotools uno::Sequence<double> aPaletteEntry; for( sal_uInt16 j=0; j<nPaletteEntries; ++j ) { - if( !xPalette->getIndex(aPaletteEntry,j) && - nAlphaDepth == 0 ) - { - nAlphaDepth = 1; - } + bool b = xPalette->getIndex(aPaletteEntry,j); + ENSURE_OR_THROW(b, "transparent entry in palette unsupported"); uno::Sequence<rendering::RGBColor> aColors=xPalColorSpace->convertToRGB(aPaletteEntry); ENSURE_OR_THROW(aColors.getLength() == 1, "Palette returned more or less than one entry"); @@ -266,47 +260,35 @@ namespace vcl::unotools sizeFromIntegerSize2D(xInputBitmap->getSize())); // normalize bitcount - auto ePixelFormat = - ( nDepth <= 8 ) ? vcl::PixelFormat::N8_BPP : - vcl::PixelFormat::N24_BPP; - auto eAlphaPixelFormat = vcl::PixelFormat::N8_BPP; + vcl::PixelFormat ePixelFormat; + if (bHasAlpha) + ePixelFormat = vcl::PixelFormat::N32_BPP; + else if ( nDepth <= 8 ) + ePixelFormat = vcl::PixelFormat::N8_BPP; + else + ePixelFormat = vcl::PixelFormat::N24_BPP; ::Bitmap aBitmap( aPixelSize, ePixelFormat, aLayout.Palette.is() ? &aPalette : nullptr ); - ::Bitmap aAlpha; - if( nAlphaDepth ) - aAlpha = Bitmap(aPixelSize, - eAlphaPixelFormat, - &Bitmap::GetGreyPalette( - sal::static_int_cast<sal_uInt16>(1 << nAlphaDepth)) ); { // limit scoped access BitmapScopedWriteAccess pWriteAccess( aBitmap ); - BitmapScopedWriteAccess pAlphaWriteAccess; - if (nAlphaDepth) - pAlphaWriteAccess = aAlpha; - ENSURE_OR_THROW(pWriteAccess.get() != nullptr, "Cannot get write access to bitmap"); const sal_Int32 nWidth(aPixelSize.Width()); const sal_Int32 nHeight(aPixelSize.Height()); - if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap, - pWriteAccess,pAlphaWriteAccess) ) + if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap,pWriteAccess,bHasAlpha) ) continue; } // limit scoped access - if( nAlphaDepth ) - return ::BitmapEx( aBitmap, - AlphaMask( aAlpha ) ); - else - return ::BitmapEx( aBitmap ); + return aBitmap; } // failed to read data 10 times - bail out - return ::BitmapEx(); + return ::Bitmap(); } geometry::RealSize2D size2DFromSize( const Size& rSize )