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 )

Reply via email to