tdf#91017 Enhance WMF import of EMR_ALPHABLEND action

The EMR_ALPHABLEND action was added 2012/2013, but missed support for
Bitmaps with Mask/Alpha. Due to that files with WMF containing these
actions may look different from before. Added suport to load contained
Mask/Alpha information in DIBs and the needed additional processing
through the display chain. WMF import is still based on Metafile
creation, when it would be using Primitives more original data could be
preserved.

Change-Id: I577569848cee2528328181fa0c7eb7f87857d094
Reviewed-on: https://gerrit.libreoffice.org/21709
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Noel Grandin <noelgrandin@gmail.com>
Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de>
diff --git a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
index c9ef7ab..62d11c4 100644
--- a/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
+++ b/drawinglayer/source/processor2d/vclhelperbufferdevice.cxx
@@ -297,6 +297,9 @@ namespace drawinglayer

            // copy AA flag for new target
            mpContent->SetAntialiasing(mrOutDev.GetAntialiasing());

            // copy RasterOp (e.g. may be ROP_XOR on destination)
            mpContent->SetRasterOp(mrOutDev.GetRasterOp());
        }
    }

@@ -325,28 +328,50 @@ namespace drawinglayer
            const Point aEmptyPoint;
            const Size aSizePixel(maDestPixel.GetSize());
            const bool bWasEnabledDst(mrOutDev.IsMapModeEnabled());
#ifdef DBG_UTIL
            static bool bDoSaveForVisualControl(false);
#endif

            mrOutDev.EnableMapMode(false);
            mpContent->EnableMapMode(false);
            Bitmap aContent(mpContent->GetBitmap(aEmptyPoint, aSizePixel));

#ifdef DBG_UTIL
            if(bDoSaveForVisualControl)
            {
                SvFileStream aNew( "c:\\content.bmp", StreamMode::WRITE|StreamMode::TRUNC);
                SvFileStream aNew(
#ifdef WNT
                    "c:\\content.bmp",
#else
                    "~/content.bmp",
#endif
                    StreamMode::WRITE|StreamMode::TRUNC);
                WriteDIB(aContent, aNew, false, true);
            }
#endif

            // during painting the buffer, disable evtl. set RasterOp (may be ROP_XOR)
            const RasterOp aOrigRasterOp(mrOutDev.GetRasterOp());
            mrOutDev.SetRasterOp(ROP_OVERPAINT);

            if(mpAlpha)
            {
                mpAlpha->EnableMapMode(false);
                const AlphaMask aAlphaMask(mpAlpha->GetBitmap(aEmptyPoint, aSizePixel));

#ifdef DBG_UTIL
                if(bDoSaveForVisualControl)
                {
                    SvFileStream aNew( "c:\\transparence.bmp", StreamMode::WRITE|StreamMode::TRUNC);
                    SvFileStream aNew(
#ifdef WNT
                        "c:\\transparence.bmp",
#else
                        "~/transparence.bmp",
#endif
                        StreamMode::WRITE|StreamMode::TRUNC);
                    WriteDIB(aAlphaMask.GetBitmap(), aNew, false, true);
                }
#endif

                mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aAlphaMask));
            }
@@ -355,11 +380,19 @@ namespace drawinglayer
                mpMask->EnableMapMode(false);
                const Bitmap aMask(mpMask->GetBitmap(aEmptyPoint, aSizePixel));

#ifdef DBG_UTIL
                if(bDoSaveForVisualControl)
                {
                    SvFileStream aNew( "c:\\mask.bmp", StreamMode::WRITE|StreamMode::TRUNC);
                    SvFileStream aNew(
#ifdef WNT
                        "c:\\mask.bmp",
#else
                        "~/mask.bmp",
#endif
                        StreamMode::WRITE|StreamMode::TRUNC);
                    WriteDIB(aMask, aNew, false, true);
                }
#endif

                mrOutDev.DrawBitmapEx(maDestPixel.TopLeft(), BitmapEx(aContent, aMask));
            }
@@ -374,6 +407,7 @@ namespace drawinglayer
                mrOutDev.DrawBitmap(maDestPixel.TopLeft(), aContent);
            }

            mrOutDev.SetRasterOp(aOrigRasterOp);
            mrOutDev.EnableMapMode(bWasEnabledDst);
        }
    }
diff --git a/include/vcl/dibtools.hxx b/include/vcl/dibtools.hxx
index 079ff9e..c9e98c4 100644
--- a/include/vcl/dibtools.hxx
+++ b/include/vcl/dibtools.hxx
@@ -23,6 +23,7 @@
#include <vcl/mapmod.hxx>
#include <tools/rc.hxx>
#include <vcl/region.hxx>
#include <vcl/alpha.hxx>

// predefines

@@ -51,7 +52,7 @@ bool VCL_DLLPUBLIC ReadDIBBitmapEx(

bool VCL_DLLPUBLIC ReadDIBV5(
    Bitmap& rTarget,
    Bitmap& rTargetAlpha,
    AlphaMask& rTargetAlpha,
    SvStream& rIStm);


@@ -66,6 +67,9 @@ bool VCL_DLLPUBLIC WriteDIBBitmapEx(
    const BitmapEx& rSource,
    SvStream& rOStm);

sal_uInt32 getDIBInfoHeaderSize();
sal_uInt32 getDIBV5HeaderSize();

#endif // INCLUDED_VCL_DIBTOOLS_HXX


diff --git a/svtools/source/misc/transfer.cxx b/svtools/source/misc/transfer.cxx
index ccad405..2650d9c 100644
--- a/svtools/source/misc/transfer.cxx
+++ b/svtools/source/misc/transfer.cxx
@@ -1673,13 +1673,13 @@ bool TransferableDataHelper::GetBitmapEx( const DataFlavor& rFlavor, BitmapEx& r
        if(rBmpEx.IsEmpty())
        {
            Bitmap aBitmap;
            Bitmap aMask;
            AlphaMask aMask;

            // explicitely use Bitmap::Read with bFileHeader = sal_True
            // #i124085# keep DIBV5 for read from clipboard, but should not happen
            ReadDIBV5(aBitmap, aMask, *xStm);

            if(aMask.IsEmpty())
            if(aMask.GetBitmap().IsEmpty())
            {
                rBmpEx = aBitmap;
            }
diff --git a/vcl/source/filter/wmf/enhwmf.cxx b/vcl/source/filter/wmf/enhwmf.cxx
index 3becfbe..f8341e3 100644
--- a/vcl/source/filter/wmf/enhwmf.cxx
+++ b/vcl/source/filter/wmf/enhwmf.cxx
@@ -23,6 +23,11 @@
#include <vcl/dibtools.hxx>
#include <memory>

#ifdef DBG_UTIL
#include <tools/stream.hxx>
#include <vcl/pngwrite.hxx>
#endif

using namespace std;

// GDI-Array
@@ -1208,43 +1213,110 @@ bool EnhWMFReader::ReadEnhWMF()
                               .ReadUInt32( offBitsSrc ).ReadUInt32( cbBitsSrc ).ReadInt32( cxSrc ).ReadInt32( cySrc ) ;

                    sal_uInt32  dwRop = SRCAND|SRCINVERT;

                    Bitmap      aBitmap;
                    Rectangle   aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );

                    if ( (cbBitsSrc > (SAL_MAX_UINT32 - 14)) || ((SAL_MAX_UINT32 - 14) - cbBitsSrc < cbBmiSrc) )
                        bStatus = false;
                    else
                    {
                        sal_uInt32 nSize = cbBmiSrc + cbBitsSrc + 14;
                        if ( nSize <= ( nEndPos - nStartPos ) )
                        const sal_uInt32 nSourceSize = cbBmiSrc + cbBitsSrc + 14;
                        if ( nSourceSize <= ( nEndPos - nStartPos ) )
                        {
                            char* pBuf = new char[ nSize ];
                            SvMemoryStream aTmp( pBuf, nSize, StreamMode::READ | StreamMode::WRITE );
                            // we need to read alpha channel data if AlphaFormat of BLENDFUNCTION is
                            // AC_SRC_ALPHA (==0x01). To read it, create a temp DIB-File which is ready
                            // for DIB-5 format
                            const bool bReadAlpha(0x01 == aFunc.aAlphaFormat);
                            const sal_uInt32 nDeltaToDIB5HeaderSize(bReadAlpha ? getDIBV5HeaderSize() - cbBmiSrc : 0);
                            const sal_uInt32 nTargetSize(cbBmiSrc + nDeltaToDIB5HeaderSize + cbBitsSrc + 14);
                            char* pBuf = new char[ nTargetSize ];
                            SvMemoryStream aTmp( pBuf, nTargetSize, StreamMode::READ | StreamMode::WRITE );

                            aTmp.ObjectOwnsMemory( true );

                            // write BM-Header (14 bytes)
                            aTmp.WriteUChar( 'B' )
                                .WriteUChar( 'M' )
                                .WriteUInt32( cbBitsSrc )
                                .WriteUInt16( 0 )
                                .WriteUInt16( 0 )
                                .WriteUInt32( cbBmiSrc + 14 );
                                .WriteUInt32( cbBmiSrc + nDeltaToDIB5HeaderSize + 14 );

                            // copy DIBInfoHeader from source (cbBmiSrc bytes)
                            pWMF->Seek( nStart + offBmiSrc );
                            pWMF->Read( pBuf + 14, cbBmiSrc );
                            pWMF->Seek( nStart + offBitsSrc );
                            pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
                            aTmp.Seek( 0 );
                            ReadDIB(aBitmap, aTmp, true);

                            // test if it is sensible to crop
                            if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
                                ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
                                    ( xSrc + cxSrc <= aBitmap.GetSizePixel().Width() ) &&
                                        ( ySrc + cySrc <= aBitmap.GetSizePixel().Height() ) )
                            if(bReadAlpha)
                            {
                                Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );
                                aBitmap.Crop( aCropRect );
                                // need to add values for all stuff that DIBV5Header is bigger
                                // than DIBInfoHeader, all values are correctly initialized to zero,
                                // so we can use memset here
                                memset(pBuf + cbBmiSrc + 14, 0, nDeltaToDIB5HeaderSize);
                            }
                            aBmpSaveList.emplace_back(new BSaveStruct(aBitmap, aRect, dwRop));

                            // copy bitmap data from source (offBitsSrc bytes)
                            pWMF->Seek( nStart + offBitsSrc );
                            pWMF->Read( pBuf + 14 + nDeltaToDIB5HeaderSize + cbBmiSrc, cbBitsSrc );
                            aTmp.Seek( 0 );

                            // prepare to read and fill BitmapEx
                            BitmapEx aBitmapEx;

                            if(bReadAlpha)
                            {
                                Bitmap aBitmap;
                                AlphaMask aAlpha;

                                if(ReadDIBV5(aBitmap, aAlpha, aTmp))
                                {
                                    aBitmapEx = BitmapEx(aBitmap, aAlpha);
                                }
                            }
                            else
                            {
                                Bitmap aBitmap;

                                if(ReadDIB(aBitmap, aTmp, true))
                                {
                                    if(0xff != aFunc.aSrcConstantAlpha)
                                    {
                                        // add const alpha channel
                                        aBitmapEx = BitmapEx(
                                            aBitmap,
                                            AlphaMask(aBitmap.GetSizePixel(), &aFunc.aSrcConstantAlpha));
                                    }
                                    else
                                    {
                                        // just use Bitmap
                                        aBitmapEx = BitmapEx(aBitmap);
                                    }
                                }
                            }

                            if(!aBitmapEx.IsEmpty())
                            {
                                // test if it is sensible to crop
                                if ( ( cxSrc > 0 ) && ( cySrc > 0 ) &&
                                    ( xSrc >= 0 ) && ( ySrc >= 0 ) &&
                                        ( xSrc + cxSrc < aBitmapEx.GetSizePixel().Width() ) &&
                                            ( ySrc + cySrc < aBitmapEx.GetSizePixel().Height() ) )
                                {
                                    const Rectangle aCropRect( Point( xSrc, ySrc ), Size( cxSrc, cySrc ) );

                                    aBitmapEx.Crop( aCropRect );
                                }

#ifdef DBG_UTIL
                                static bool bDoSaveForVisualControl(false);

                                if(bDoSaveForVisualControl)
                                {
                                    SvFileStream aNew(OUString("c:\\metafile_content.png"), StreamMode::WRITE|StreamMode::TRUNC);
                                    vcl::PNGWriter aPNGWriter(aBitmapEx);
                                    aPNGWriter.Write(aNew);
                                }
#endif
                                aBmpSaveList.emplace_back(new BSaveStruct(aBitmapEx, aRect, dwRop));
                            }
                        }
                    }
                }
diff --git a/vcl/source/filter/wmf/winmtf.cxx b/vcl/source/filter/wmf/winmtf.cxx
index 39ed115..60aa409 100644
--- a/vcl/source/filter/wmf/winmtf.cxx
+++ b/vcl/source/filter/wmf/winmtf.cxx
@@ -1543,19 +1543,68 @@ void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const B

        // #i50672# Extract whole VDev content (to match size of rBitmap)
        pVDev->EnableMapMode( false );
        Bitmap aMask( pVDev->GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) );
        const Bitmap aVDevMask(pVDev->GetBitmap(aEmptyPoint, aSizePixel));

        if ( aBmpEx.IsTransparent() )
        if(aBmpEx.IsTransparent())
        {
            if ( rBitmap.GetTransparentColor() == Color( COL_WHITE ) )
                aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_OR );
            // bitmap already uses a Mask or Alpha, we need to blend that with
            // the new masking in pVDev
            if(aBmpEx.IsAlpha())
            {
                // need to blend in AlphaMask quality (8Bit)
                AlphaMask fromVDev(aVDevMask);
                AlphaMask fromBmpEx(aBmpEx.GetAlpha());
                BitmapReadAccess* pR = fromVDev.AcquireReadAccess();
                BitmapWriteAccess* pW = fromBmpEx.AcquireWriteAccess();

                if(pR && pW)
                {
                    const long nWidth(std::min(pR->Width(), pW->Width()));
                    const long nHeight(std::min(pR->Height(), pW->Height()));

                    for(long nY(0); nY < nHeight; nY++) for(long nX(0); nX < nWidth; nX++)
                    {
                        const sal_uInt8 nIndR(pR->GetPixelIndex(nY, nX));
                        const sal_uInt8 nIndW(pW->GetPixelIndex(nY, nX));

                        // these values represent transparency (0 == no, 255 == fully transparent),
                        // so to blend these we have to multiply the inverse (opacity)
                        // and re-invert the result to transparence
                        const sal_uInt8 nCombined(0x00ff - (((0x00ff - nIndR) * (0x00ff - nIndW)) >> 8));

                        pW->SetPixelIndex(nY, nX, nCombined);
                    }
                }

                fromVDev.ReleaseAccess(pR);
                fromBmpEx.ReleaseAccess(pW);
                aBmpEx = BitmapEx(aBmpEx.GetBitmap(), fromBmpEx);
            }
            else
                aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_AND );
            aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
            {
                // need to blend in Mask quality (1Bit)
                Bitmap aMask(aVDevMask.CreateMask(Color(COL_WHITE)));

                if ( rBitmap.GetTransparentColor() == Color( COL_WHITE ) )
                {
                    aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_OR );
                }
                else
                {
                    aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_AND );
                }

                aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
            }
        }
        else
            aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
        {
            // no mask yet, create and add new mask. For better quality, use Alpha,
            // this allws the drawn mask being processed with AnitAliasing (AAed)
            aBmpEx = BitmapEx(rBitmap.GetBitmap(), aVDevMask);
        }
    }

    if ( aBmpEx.IsTransparent() )
        mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( rPos, rSize, aBmpEx ) );
    else
@@ -1622,8 +1671,8 @@ void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
                    if ( nObjectsOfSameSize == 2 )
                    {
                        BSaveStruct* pSave2 = rSaveList[i + 1].get();
                        if ( ( pSave->aBmp.GetPrefSize() == pSave2->aBmp.GetPrefSize() ) &&
                             ( pSave->aBmp.GetPrefMapMode() == pSave2->aBmp.GetPrefMapMode() ) )
                        if ( ( pSave->aBmpEx.GetPrefSize() == pSave2->aBmpEx.GetPrefSize() ) &&
                             ( pSave->aBmpEx.GetPrefMapMode() == pSave2->aBmpEx.GetPrefMapMode() ) )
                        {
                            // TODO: Strictly speaking, we should
                            // check whether mask is monochrome, and
@@ -1633,8 +1682,8 @@ void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
                            // bitmap.
                            if ( ( nWinRop == SRCPAINT ) && ( pSave2->nWinRop == SRCAND ) )
                            {
                                Bitmap aMask( pSave->aBmp ); aMask.Invert();
                                BitmapEx aBmpEx( pSave2->aBmp, aMask );
                                Bitmap aMask( pSave->aBmpEx.GetBitmap() ); aMask.Invert();
                                BitmapEx aBmpEx( pSave2->aBmpEx.GetBitmap(), aMask );
                                ImplDrawBitmap( aPos, aSize, aBmpEx );
                                bDrawn = true;
                                i++;
@@ -1644,8 +1693,8 @@ void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
                            // is inverted
                            else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCPAINT ) )
                            {
                                Bitmap aMask( pSave->aBmp );
                                BitmapEx aBmpEx( pSave2->aBmp, aMask );
                                Bitmap aMask( pSave->aBmpEx.GetBitmap() );
                                BitmapEx aBmpEx( pSave2->aBmpEx.GetBitmap(), aMask );
                                ImplDrawBitmap( aPos, aSize, aBmpEx );
                                bDrawn = true;
                                i++;
@@ -1653,8 +1702,8 @@ void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
                            // tdf#90539
                            else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCINVERT ) )
                            {
                                Bitmap aMask( pSave->aBmp );
                                BitmapEx aBmpEx( pSave2->aBmp, aMask );
                                Bitmap aMask( pSave->aBmpEx.GetBitmap() );
                                BitmapEx aBmpEx( pSave2->aBmpEx.GetBitmap(), aMask );
                                ImplDrawBitmap( aPos, aSize, aBmpEx );
                                bDrawn = true;
                                i++;
@@ -1667,24 +1716,31 @@ void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
                {
                    Push();
                    sal_uInt32  nOldRop = SetRasterOp( R2_COPYPEN );
                    Bitmap      aBitmap( pSave->aBmp );
                    Bitmap      aBitmap( pSave->aBmpEx.GetBitmap() );
                    sal_uInt32  nOperation = ( nRasterOperation & 0xf );
                    switch( nOperation )
                    {
                        case 0x1 :
                        case 0xe :
                        {
                            SetRasterOp( R2_XORPEN );
                            ImplDrawBitmap( aPos, aSize, aBitmap );
                            SetRasterOp( R2_COPYPEN );
                            Bitmap  aMask( aBitmap );
                            aMask.Invert();
                            BitmapEx aBmpEx( aBitmap, aMask );
                            ImplDrawBitmap( aPos, aSize, aBmpEx );
                            if ( nOperation == 0x1 )
                            if(pSave->aBmpEx.IsAlpha())
                            {
                                SetRasterOp( R2_NOT );
                                DrawRect( aRect, false );
                                ImplDrawBitmap( aPos, aSize, pSave->aBmpEx );
                            }
                            else
                            {
                                SetRasterOp( R2_XORPEN );
                                ImplDrawBitmap( aPos, aSize, aBitmap );
                                SetRasterOp( R2_COPYPEN );
                                Bitmap  aMask( aBitmap );
                                aMask.Invert();
                                BitmapEx aBmpEx( aBitmap, aMask );
                                ImplDrawBitmap( aPos, aSize, aBmpEx );
                                if ( nOperation == 0x1 )
                                {
                                    SetRasterOp( R2_NOT );
                                    DrawRect( aRect, false );
                                }
                            }
                        }
                        break;
diff --git a/vcl/source/filter/wmf/winmtf.hxx b/vcl/source/filter/wmf/winmtf.hxx
index 5e07885..23ce3ad 100644
--- a/vcl/source/filter/wmf/winmtf.hxx
+++ b/vcl/source/filter/wmf/winmtf.hxx
@@ -443,15 +443,20 @@ typedef std::shared_ptr<SaveStruct> SaveStructPtr;

struct BSaveStruct
{
    Bitmap          aBmp;
    BitmapEx        aBmpEx;
    Rectangle       aOutRect;
    sal_uInt32      nWinRop;

    BSaveStruct(const Bitmap& rBmp, const Rectangle& rOutRect,
                sal_uInt32 nRop)
        : aBmp(rBmp)
        , aOutRect(rOutRect)
        , nWinRop(nRop)
    BSaveStruct(const Bitmap& rBmp, const Rectangle& rOutRect, sal_uInt32 nRop)
    :   aBmpEx(rBmp)
    ,   aOutRect(rOutRect)
    ,   nWinRop(nRop)
    {}

    BSaveStruct(const BitmapEx& rBmpEx, const Rectangle& rOutRect, sal_uInt32 nRop)
    :   aBmpEx(rBmpEx)
    ,   aOutRect(rOutRect)
    ,   nWinRop(nRop)
    {}
};

diff --git a/vcl/source/gdi/dibtools.cxx b/vcl/source/gdi/dibtools.cxx
index a788c52..afb0a64 100644
--- a/vcl/source/gdi/dibtools.cxx
+++ b/vcl/source/gdi/dibtools.cxx
@@ -737,7 +737,7 @@ bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& r
    return( rIStm.GetError() == 0UL );
}

bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLong nOffset, bool bMSOFormat = false )
bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, AlphaMask* pBmpAlpha, sal_uLong nOffset, bool bMSOFormat = false )
{
    DIBV5Header aHeader;
    const sal_uLong nStmPos = rIStm.Tell();
@@ -869,7 +869,7 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLon
            Bitmap::ReleaseAccess(pAcc);
            return false;
        }
        Bitmap aNewBmpAlpha;
        AlphaMask aNewBmpAlpha;
        BitmapWriteAccess* pAccAlpha = nullptr;
        bool bAlphaPossible(pBmpAlpha && aHeader.nBitCount == 32);

@@ -891,7 +891,7 @@ bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLon

        if (bAlphaPossible)
        {
            aNewBmpAlpha = Bitmap(aSizePixel, 8);
            aNewBmpAlpha = AlphaMask(aSizePixel);
            pAccAlpha = aNewBmpAlpha.AcquireWriteAccess();
        }

@@ -1523,8 +1523,8 @@ bool ImplWriteDIBFileHeader(SvStream& rOStm, BitmapReadAccess& rAcc, bool bUseDI
}

bool ImplReadDIB(
    Bitmap& rTarget, Bitmap*
    pTargetAlpha,
    Bitmap& rTarget,
    AlphaMask* pTargetAlpha,
    SvStream& rIStm,
    bool bFileHeader,
    bool bMSOFormat=false)
@@ -1726,7 +1726,7 @@ bool ReadDIBBitmapEx(

bool ReadDIBV5(
    Bitmap& rTarget,
    Bitmap& rTargetAlpha,
    AlphaMask& rTargetAlpha,
    SvStream& rIStm)
{
    return ImplReadDIB(rTarget, &rTargetAlpha, rIStm, true);
@@ -1765,4 +1765,14 @@ bool WriteDIBBitmapEx(
    return false;
}

sal_uInt32 getDIBInfoHeaderSize()
{
    return DIBINFOHEADERSIZE;
}

sal_uInt32 getDIBV5HeaderSize()
{
    return DIBV5HEADERSIZE;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */