xref: /trunk/main/vcl/source/gdi/dibtools.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
145fd3b9aSArmin Le Grand /**************************************************************
245fd3b9aSArmin Le Grand  *
345fd3b9aSArmin Le Grand  * Licensed to the Apache Software Foundation (ASF) under one
445fd3b9aSArmin Le Grand  * or more contributor license agreements.  See the NOTICE file
545fd3b9aSArmin Le Grand  * distributed with this work for additional information
645fd3b9aSArmin Le Grand  * regarding copyright ownership.  The ASF licenses this file
745fd3b9aSArmin Le Grand  * to you under the Apache License, Version 2.0 (the
845fd3b9aSArmin Le Grand  * "License"); you may not use this file except in compliance
945fd3b9aSArmin Le Grand  * with the License.  You may obtain a copy of the License at
1045fd3b9aSArmin Le Grand  *
1145fd3b9aSArmin Le Grand  *   http://www.apache.org/licenses/LICENSE-2.0
1245fd3b9aSArmin Le Grand  *
1345fd3b9aSArmin Le Grand  * Unless required by applicable law or agreed to in writing,
1445fd3b9aSArmin Le Grand  * software distributed under the License is distributed on an
1545fd3b9aSArmin Le Grand  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1645fd3b9aSArmin Le Grand  * KIND, either express or implied.  See the License for the
1745fd3b9aSArmin Le Grand  * specific language governing permissions and limitations
1845fd3b9aSArmin Le Grand  * under the License.
1945fd3b9aSArmin Le Grand  *
2045fd3b9aSArmin Le Grand  *************************************************************/
2145fd3b9aSArmin Le Grand 
2245fd3b9aSArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove
2345fd3b9aSArmin Le Grand #include "precompiled_vcl.hxx"
2445fd3b9aSArmin Le Grand 
2545fd3b9aSArmin Le Grand #include <vcl/salbtype.hxx>
2645fd3b9aSArmin Le Grand #include <vcl/dibtools.hxx>
2745fd3b9aSArmin Le Grand #include <tools/zcodec.hxx>
2845fd3b9aSArmin Le Grand #include <tools/stream.hxx>
2945fd3b9aSArmin Le Grand #include <vcl/bitmapex.hxx>
3045fd3b9aSArmin Le Grand #include <vcl/bmpacc.hxx>
3145fd3b9aSArmin Le Grand #include <vcl/outdev.hxx>
3245fd3b9aSArmin Le Grand 
3345fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
3445fd3b9aSArmin Le Grand // - Defines -
3545fd3b9aSArmin Le Grand 
3645fd3b9aSArmin Le Grand #define DIBCOREHEADERSIZE       ( 12UL )
3745fd3b9aSArmin Le Grand #define DIBINFOHEADERSIZE       ( sizeof(DIBInfoHeader) )
3845fd3b9aSArmin Le Grand #define DIBV5HEADERSIZE         ( sizeof(DIBV5Header) )
3945fd3b9aSArmin Le Grand 
4045fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
4145fd3b9aSArmin Le Grand // - Compression defines
4245fd3b9aSArmin Le Grand 
4345fd3b9aSArmin Le Grand #define COMPRESS_OWN                ('S'|('D'<<8UL))
4445fd3b9aSArmin Le Grand #define COMPRESS_NONE               ( 0UL )
4545fd3b9aSArmin Le Grand #define RLE_8                       ( 1UL )
4645fd3b9aSArmin Le Grand #define RLE_4                       ( 2UL )
4745fd3b9aSArmin Le Grand #define BITFIELDS                   ( 3UL )
4845fd3b9aSArmin Le Grand #define ZCOMPRESS                   ( COMPRESS_OWN | 0x01000000UL ) /* == 'SD01' (binary) */
4945fd3b9aSArmin Le Grand 
5045fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
5145fd3b9aSArmin Le Grand // - DIBInfoHeader and DIBV5Header
5245fd3b9aSArmin Le Grand 
5345fd3b9aSArmin Le Grand typedef sal_Int32 FXPT2DOT30;
5445fd3b9aSArmin Le Grand 
5545fd3b9aSArmin Le Grand struct CIEXYZ
5645fd3b9aSArmin Le Grand {
5745fd3b9aSArmin Le Grand     FXPT2DOT30      aXyzX;
5845fd3b9aSArmin Le Grand     FXPT2DOT30      aXyzY;
5945fd3b9aSArmin Le Grand     FXPT2DOT30      aXyzZ;
6045fd3b9aSArmin Le Grand 
CIEXYZCIEXYZ6145fd3b9aSArmin Le Grand     CIEXYZ()
6245fd3b9aSArmin Le Grand     :   aXyzX(0L),
6345fd3b9aSArmin Le Grand         aXyzY(0L),
6445fd3b9aSArmin Le Grand         aXyzZ(0L)
6545fd3b9aSArmin Le Grand     {}
6645fd3b9aSArmin Le Grand 
~CIEXYZCIEXYZ6745fd3b9aSArmin Le Grand     ~CIEXYZ()
6845fd3b9aSArmin Le Grand     {}
6945fd3b9aSArmin Le Grand };
7045fd3b9aSArmin Le Grand 
7145fd3b9aSArmin Le Grand struct CIEXYZTriple
7245fd3b9aSArmin Le Grand {
7345fd3b9aSArmin Le Grand     CIEXYZ          aXyzRed;
7445fd3b9aSArmin Le Grand     CIEXYZ          aXyzGreen;
7545fd3b9aSArmin Le Grand     CIEXYZ          aXyzBlue;
7645fd3b9aSArmin Le Grand 
CIEXYZTripleCIEXYZTriple7745fd3b9aSArmin Le Grand     CIEXYZTriple()
7845fd3b9aSArmin Le Grand     :   aXyzRed(),
7945fd3b9aSArmin Le Grand         aXyzGreen(),
8045fd3b9aSArmin Le Grand         aXyzBlue()
8145fd3b9aSArmin Le Grand     {}
8245fd3b9aSArmin Le Grand 
~CIEXYZTripleCIEXYZTriple8345fd3b9aSArmin Le Grand     ~CIEXYZTriple()
8445fd3b9aSArmin Le Grand     {}
8545fd3b9aSArmin Le Grand };
8645fd3b9aSArmin Le Grand 
8745fd3b9aSArmin Le Grand struct DIBInfoHeader
8845fd3b9aSArmin Le Grand {
8945fd3b9aSArmin Le Grand     sal_uInt32      nSize;
9045fd3b9aSArmin Le Grand     sal_Int32       nWidth;
9145fd3b9aSArmin Le Grand     sal_Int32       nHeight;
9245fd3b9aSArmin Le Grand     sal_uInt16      nPlanes;
9345fd3b9aSArmin Le Grand     sal_uInt16      nBitCount;
9445fd3b9aSArmin Le Grand     sal_uInt32      nCompression;
9545fd3b9aSArmin Le Grand     sal_uInt32      nSizeImage;
9645fd3b9aSArmin Le Grand     sal_Int32       nXPelsPerMeter;
9745fd3b9aSArmin Le Grand     sal_Int32       nYPelsPerMeter;
9845fd3b9aSArmin Le Grand     sal_uInt32      nColsUsed;
9945fd3b9aSArmin Le Grand     sal_uInt32      nColsImportant;
10045fd3b9aSArmin Le Grand 
DIBInfoHeaderDIBInfoHeader10145fd3b9aSArmin Le Grand     DIBInfoHeader()
10245fd3b9aSArmin Le Grand     :   nSize(0UL),
10345fd3b9aSArmin Le Grand         nWidth(0UL),
10445fd3b9aSArmin Le Grand         nHeight(0UL),
10545fd3b9aSArmin Le Grand         nPlanes(0),
10645fd3b9aSArmin Le Grand         nBitCount(0),
10745fd3b9aSArmin Le Grand         nCompression(0),
10845fd3b9aSArmin Le Grand         nSizeImage(0),
10945fd3b9aSArmin Le Grand         nXPelsPerMeter(0UL),
11045fd3b9aSArmin Le Grand         nYPelsPerMeter(0UL),
11145fd3b9aSArmin Le Grand         nColsUsed(0UL),
11245fd3b9aSArmin Le Grand         nColsImportant(0UL)
11345fd3b9aSArmin Le Grand     {}
11445fd3b9aSArmin Le Grand 
~DIBInfoHeaderDIBInfoHeader11545fd3b9aSArmin Le Grand     ~DIBInfoHeader()
11645fd3b9aSArmin Le Grand     {}
11745fd3b9aSArmin Le Grand };
11845fd3b9aSArmin Le Grand 
11945fd3b9aSArmin Le Grand struct DIBV5Header : public DIBInfoHeader
12045fd3b9aSArmin Le Grand {
12145fd3b9aSArmin Le Grand     sal_uInt32      nV5RedMask;
12245fd3b9aSArmin Le Grand     sal_uInt32      nV5GreenMask;
12345fd3b9aSArmin Le Grand     sal_uInt32      nV5BlueMask;
12445fd3b9aSArmin Le Grand     sal_uInt32      nV5AlphaMask;
12545fd3b9aSArmin Le Grand     sal_uInt32      nV5CSType;
12645fd3b9aSArmin Le Grand     CIEXYZTriple    aV5Endpoints;
12745fd3b9aSArmin Le Grand     sal_uInt32      nV5GammaRed;
12845fd3b9aSArmin Le Grand     sal_uInt32      nV5GammaGreen;
12945fd3b9aSArmin Le Grand     sal_uInt32      nV5GammaBlue;
13045fd3b9aSArmin Le Grand     sal_uInt32      nV5Intent;
13145fd3b9aSArmin Le Grand     sal_uInt32      nV5ProfileData;
13245fd3b9aSArmin Le Grand     sal_uInt32      nV5ProfileSize;
13345fd3b9aSArmin Le Grand     sal_uInt32      nV5Reserved;
13445fd3b9aSArmin Le Grand 
DIBV5HeaderDIBV5Header13545fd3b9aSArmin Le Grand     DIBV5Header()
13645fd3b9aSArmin Le Grand     :   DIBInfoHeader(),
13745fd3b9aSArmin Le Grand         nV5RedMask(0UL),
13845fd3b9aSArmin Le Grand         nV5GreenMask(0UL),
13945fd3b9aSArmin Le Grand         nV5BlueMask(0UL),
14045fd3b9aSArmin Le Grand         nV5AlphaMask(0UL),
14145fd3b9aSArmin Le Grand         nV5CSType(0UL),
14245fd3b9aSArmin Le Grand         aV5Endpoints(),
14345fd3b9aSArmin Le Grand         nV5GammaRed(0UL),
14445fd3b9aSArmin Le Grand         nV5GammaGreen(0UL),
14545fd3b9aSArmin Le Grand         nV5GammaBlue(0UL),
14645fd3b9aSArmin Le Grand         nV5Intent(0UL),
14745fd3b9aSArmin Le Grand         nV5ProfileData(0UL),
14845fd3b9aSArmin Le Grand         nV5ProfileSize(0UL),
14945fd3b9aSArmin Le Grand         nV5Reserved(0UL)
15045fd3b9aSArmin Le Grand     {}
15145fd3b9aSArmin Le Grand 
~DIBV5HeaderDIBV5Header15245fd3b9aSArmin Le Grand     ~DIBV5Header()
15345fd3b9aSArmin Le Grand     {}
15445fd3b9aSArmin Le Grand };
15545fd3b9aSArmin Le Grand 
15645fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
15745fd3b9aSArmin Le Grand 
15845fd3b9aSArmin Le Grand namespace
15945fd3b9aSArmin Le Grand {
discretizeBitcount(sal_uInt16 nInputCount)16045fd3b9aSArmin Le Grand     inline sal_uInt16 discretizeBitcount( sal_uInt16 nInputCount )
16145fd3b9aSArmin Le Grand     {
16245fd3b9aSArmin Le Grand         return ( nInputCount <= 1 ) ? 1 :
16345fd3b9aSArmin Le Grand                ( nInputCount <= 4 ) ? 4 :
16445fd3b9aSArmin Le Grand                ( nInputCount <= 8 ) ? 8 : 24;
16545fd3b9aSArmin Le Grand     }
16645fd3b9aSArmin Le Grand 
isBitfieldCompression(sal_uLong nScanlineFormat)16745fd3b9aSArmin Le Grand     inline bool isBitfieldCompression( sal_uLong nScanlineFormat )
16845fd3b9aSArmin Le Grand     {
16945fd3b9aSArmin Le Grand         return (BMP_FORMAT_16BIT_TC_LSB_MASK == nScanlineFormat) || (BMP_FORMAT_32BIT_TC_MASK == nScanlineFormat);
17045fd3b9aSArmin Le Grand     }
17145fd3b9aSArmin Le Grand }
17245fd3b9aSArmin Le Grand 
17345fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
17445fd3b9aSArmin Le Grand 
ImplReadDIBInfoHeader(SvStream & rIStm,DIBV5Header & rHeader,bool & bTopDown)17545fd3b9aSArmin Le Grand bool ImplReadDIBInfoHeader(SvStream& rIStm, DIBV5Header& rHeader, bool& bTopDown)
17645fd3b9aSArmin Le Grand {
17745fd3b9aSArmin Le Grand     // BITMAPINFOHEADER or BITMAPCOREHEADER or BITMAPV5HEADER
17845fd3b9aSArmin Le Grand     const sal_Size aStartPos(rIStm.Tell());
17945fd3b9aSArmin Le Grand     rIStm >> rHeader.nSize;
18045fd3b9aSArmin Le Grand 
18145fd3b9aSArmin Le Grand     // BITMAPCOREHEADER
18245fd3b9aSArmin Le Grand     if ( rHeader.nSize == DIBCOREHEADERSIZE )
18345fd3b9aSArmin Le Grand     {
18445fd3b9aSArmin Le Grand         sal_Int16 nTmp16;
18545fd3b9aSArmin Le Grand 
18645fd3b9aSArmin Le Grand         rIStm >> nTmp16; rHeader.nWidth = nTmp16;
18745fd3b9aSArmin Le Grand         rIStm >> nTmp16; rHeader.nHeight = nTmp16;
18845fd3b9aSArmin Le Grand         rIStm >> rHeader.nPlanes;
18945fd3b9aSArmin Le Grand         rIStm >> rHeader.nBitCount;
19045fd3b9aSArmin Le Grand     }
19145fd3b9aSArmin Le Grand     else
19245fd3b9aSArmin Le Grand     {
19345fd3b9aSArmin Le Grand         // BITMAPCOREHEADER, BITMAPV5HEADER or unknown. Read as far as possible
19445fd3b9aSArmin Le Grand         sal_Size nUsed(sizeof(rHeader.nSize));
19545fd3b9aSArmin Le Grand 
19645fd3b9aSArmin Le Grand         // read DIBInfoHeader entries
19745fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nWidth; nUsed += sizeof(rHeader.nWidth); }
19845fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nHeight; nUsed += sizeof(rHeader.nHeight); }
19945fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nPlanes; nUsed += sizeof(rHeader.nPlanes); }
20045fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nBitCount;  nUsed += sizeof(rHeader.nBitCount); }
20145fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nCompression;  nUsed += sizeof(rHeader.nCompression); }
20245fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nSizeImage;  nUsed += sizeof(rHeader.nSizeImage); }
20345fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nXPelsPerMeter;  nUsed += sizeof(rHeader.nXPelsPerMeter); }
20445fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nYPelsPerMeter;  nUsed += sizeof(rHeader.nYPelsPerMeter); }
20545fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nColsUsed;  nUsed += sizeof(rHeader.nColsUsed); }
20645fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nColsImportant;  nUsed += sizeof(rHeader.nColsImportant); }
20745fd3b9aSArmin Le Grand 
20845fd3b9aSArmin Le Grand         // read DIBV5HEADER members
20945fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5RedMask; nUsed += sizeof(rHeader.nV5RedMask); }
21045fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GreenMask; nUsed += sizeof(rHeader.nV5GreenMask);  }
21145fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5BlueMask; nUsed += sizeof(rHeader.nV5BlueMask);  }
21245fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5AlphaMask; nUsed += sizeof(rHeader.nV5AlphaMask);  }
21345fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5CSType; nUsed += sizeof(rHeader.nV5CSType);  }
21445fd3b9aSArmin Le Grand 
21545fd3b9aSArmin Le Grand         // read contained CIEXYZTriple's
21645fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzRed.aXyzX; nUsed += sizeof(rHeader.aV5Endpoints.aXyzRed.aXyzX); }
21745fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzRed.aXyzY; nUsed += sizeof(rHeader.aV5Endpoints.aXyzRed.aXyzY); }
21845fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzRed.aXyzZ; nUsed += sizeof(rHeader.aV5Endpoints.aXyzRed.aXyzZ); }
21945fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzGreen.aXyzX; nUsed += sizeof(rHeader.aV5Endpoints.aXyzGreen.aXyzX); }
22045fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzGreen.aXyzY; nUsed += sizeof(rHeader.aV5Endpoints.aXyzGreen.aXyzY); }
22145fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzGreen.aXyzZ; nUsed += sizeof(rHeader.aV5Endpoints.aXyzGreen.aXyzZ); }
22245fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzBlue.aXyzX; nUsed += sizeof(rHeader.aV5Endpoints.aXyzBlue.aXyzX); }
22345fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzBlue.aXyzY; nUsed += sizeof(rHeader.aV5Endpoints.aXyzBlue.aXyzY); }
22445fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.aV5Endpoints.aXyzBlue.aXyzZ; nUsed += sizeof(rHeader.aV5Endpoints.aXyzBlue.aXyzZ); }
22545fd3b9aSArmin Le Grand 
22645fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GammaRed; nUsed += sizeof(rHeader.nV5GammaRed);  }
22745fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GammaGreen; nUsed += sizeof(rHeader.nV5GammaGreen);  }
22845fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5GammaBlue; nUsed += sizeof(rHeader.nV5GammaBlue);  }
22945fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5Intent; nUsed += sizeof(rHeader.nV5Intent);  }
23045fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5ProfileData; nUsed += sizeof(rHeader.nV5ProfileData);  }
23145fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5ProfileSize; nUsed += sizeof(rHeader.nV5ProfileSize);  }
23245fd3b9aSArmin Le Grand         if(nUsed < rHeader.nSize) { rIStm >> rHeader.nV5Reserved; nUsed += sizeof(rHeader.nV5Reserved);  }
23345fd3b9aSArmin Le Grand 
23445fd3b9aSArmin Le Grand         // seek to EndPos
23545fd3b9aSArmin Le Grand         rIStm.Seek(aStartPos + rHeader.nSize);
23645fd3b9aSArmin Le Grand     }
23745fd3b9aSArmin Le Grand 
23845fd3b9aSArmin Le Grand     if ( rHeader.nHeight < 0 )
23945fd3b9aSArmin Le Grand     {
24045fd3b9aSArmin Le Grand         bTopDown = true;
24145fd3b9aSArmin Le Grand         rHeader.nHeight *= -1;
24245fd3b9aSArmin Le Grand     }
24345fd3b9aSArmin Le Grand     else
24445fd3b9aSArmin Le Grand     {
24545fd3b9aSArmin Le Grand         bTopDown = false;
24645fd3b9aSArmin Le Grand     }
24745fd3b9aSArmin Le Grand 
24845fd3b9aSArmin Le Grand     if ( rHeader.nWidth < 0 )
24945fd3b9aSArmin Le Grand     {
25045fd3b9aSArmin Le Grand         rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
25145fd3b9aSArmin Le Grand     }
25245fd3b9aSArmin Le Grand 
25345fd3b9aSArmin Le Grand     // #144105# protect a little against damaged files
25445fd3b9aSArmin Le Grand     if( rHeader.nSizeImage > ( 16 * static_cast< sal_uInt32 >( rHeader.nWidth * rHeader.nHeight ) ) )
25545fd3b9aSArmin Le Grand     {
25645fd3b9aSArmin Le Grand         rHeader.nSizeImage = 0;
25745fd3b9aSArmin Le Grand     }
25845fd3b9aSArmin Le Grand 
25945fd3b9aSArmin Le Grand     return( ( rHeader.nPlanes == 1 ) && ( rIStm.GetError() == 0UL ) );
26045fd3b9aSArmin Le Grand }
26145fd3b9aSArmin Le Grand 
ImplReadDIBPalette(SvStream & rIStm,BitmapWriteAccess & rAcc,bool bQuad)26245fd3b9aSArmin Le Grand bool ImplReadDIBPalette( SvStream& rIStm, BitmapWriteAccess& rAcc, bool bQuad )
26345fd3b9aSArmin Le Grand {
26445fd3b9aSArmin Le Grand     const sal_uInt16    nColors = rAcc.GetPaletteEntryCount();
26545fd3b9aSArmin Le Grand     const sal_uLong     nPalSize = nColors * ( bQuad ? 4UL : 3UL );
26645fd3b9aSArmin Le Grand     BitmapColor     aPalColor;
26745fd3b9aSArmin Le Grand 
26845fd3b9aSArmin Le Grand     sal_uInt8* pEntries = new sal_uInt8[ nPalSize ];
26945fd3b9aSArmin Le Grand     rIStm.Read( pEntries, nPalSize );
27045fd3b9aSArmin Le Grand 
27145fd3b9aSArmin Le Grand     sal_uInt8* pTmpEntry = pEntries;
27245fd3b9aSArmin Le Grand     for( sal_uInt16 i = 0; i < nColors; i++ )
27345fd3b9aSArmin Le Grand     {
27445fd3b9aSArmin Le Grand         aPalColor.SetBlue( *pTmpEntry++ );
27545fd3b9aSArmin Le Grand         aPalColor.SetGreen( *pTmpEntry++ );
27645fd3b9aSArmin Le Grand         aPalColor.SetRed( *pTmpEntry++ );
27745fd3b9aSArmin Le Grand 
27845fd3b9aSArmin Le Grand         if( bQuad )
27945fd3b9aSArmin Le Grand             pTmpEntry++;
28045fd3b9aSArmin Le Grand 
28145fd3b9aSArmin Le Grand         rAcc.SetPaletteColor( i, aPalColor );
28245fd3b9aSArmin Le Grand     }
28345fd3b9aSArmin Le Grand 
28445fd3b9aSArmin Le Grand     delete[] pEntries;
28545fd3b9aSArmin Le Grand 
28645fd3b9aSArmin Le Grand     return( rIStm.GetError() == 0UL );
28745fd3b9aSArmin Le Grand }
28845fd3b9aSArmin Le Grand 
ImplDecodeRLE(sal_uInt8 * pBuffer,DIBV5Header & rHeader,BitmapWriteAccess & rAcc,bool bRLE4)28945fd3b9aSArmin Le Grand void ImplDecodeRLE( sal_uInt8* pBuffer, DIBV5Header& rHeader, BitmapWriteAccess& rAcc, bool bRLE4 )
29045fd3b9aSArmin Le Grand {
29145fd3b9aSArmin Le Grand     Scanline    pRLE = pBuffer;
29245fd3b9aSArmin Le Grand     long        nY = rHeader.nHeight - 1L;
29345fd3b9aSArmin Le Grand     const sal_uLong nWidth = rAcc.Width();
29445fd3b9aSArmin Le Grand     sal_uLong       nCountByte;
29545fd3b9aSArmin Le Grand     sal_uLong       nRunByte;
29645fd3b9aSArmin Le Grand     sal_uLong       nX = 0UL;
29745fd3b9aSArmin Le Grand     sal_uInt8       cTmp;
29845fd3b9aSArmin Le Grand     bool        bEndDecoding = false;
29945fd3b9aSArmin Le Grand 
30045fd3b9aSArmin Le Grand     do
30145fd3b9aSArmin Le Grand     {
30245fd3b9aSArmin Le Grand         if( ( nCountByte = *pRLE++ ) == 0 )
30345fd3b9aSArmin Le Grand         {
30445fd3b9aSArmin Le Grand             nRunByte = *pRLE++;
30545fd3b9aSArmin Le Grand 
30645fd3b9aSArmin Le Grand             if( nRunByte > 2 )
30745fd3b9aSArmin Le Grand             {
30845fd3b9aSArmin Le Grand                 if( bRLE4 )
30945fd3b9aSArmin Le Grand                 {
31045fd3b9aSArmin Le Grand                     nCountByte = nRunByte >> 1;
31145fd3b9aSArmin Le Grand 
31245fd3b9aSArmin Le Grand                     for( sal_uLong i = 0UL; i < nCountByte; i++ )
31345fd3b9aSArmin Le Grand                     {
31445fd3b9aSArmin Le Grand                         cTmp = *pRLE++;
31545fd3b9aSArmin Le Grand 
31645fd3b9aSArmin Le Grand                         if( nX < nWidth )
31745fd3b9aSArmin Le Grand                             rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 );
31845fd3b9aSArmin Le Grand 
31945fd3b9aSArmin Le Grand                         if( nX < nWidth )
32045fd3b9aSArmin Le Grand                             rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f );
32145fd3b9aSArmin Le Grand                     }
32245fd3b9aSArmin Le Grand 
32345fd3b9aSArmin Le Grand                     if( nRunByte & 1 )
32445fd3b9aSArmin Le Grand                     {
32545fd3b9aSArmin Le Grand                         if( nX < nWidth )
32645fd3b9aSArmin Le Grand                             rAcc.SetPixelIndex( nY, nX++, *pRLE >> 4 );
32745fd3b9aSArmin Le Grand 
32845fd3b9aSArmin Le Grand                         pRLE++;
32945fd3b9aSArmin Le Grand                     }
33045fd3b9aSArmin Le Grand 
33145fd3b9aSArmin Le Grand                     if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
33245fd3b9aSArmin Le Grand                         pRLE++;
33345fd3b9aSArmin Le Grand                 }
33445fd3b9aSArmin Le Grand                 else
33545fd3b9aSArmin Le Grand                 {
33645fd3b9aSArmin Le Grand                     for( sal_uLong i = 0UL; i < nRunByte; i++ )
33745fd3b9aSArmin Le Grand                     {
33845fd3b9aSArmin Le Grand                         if( nX < nWidth )
33945fd3b9aSArmin Le Grand                             rAcc.SetPixelIndex( nY, nX++, *pRLE );
34045fd3b9aSArmin Le Grand 
34145fd3b9aSArmin Le Grand                         pRLE++;
34245fd3b9aSArmin Le Grand                     }
34345fd3b9aSArmin Le Grand 
34445fd3b9aSArmin Le Grand                     if( nRunByte & 1 )
34545fd3b9aSArmin Le Grand                         pRLE++;
34645fd3b9aSArmin Le Grand                 }
34745fd3b9aSArmin Le Grand             }
34845fd3b9aSArmin Le Grand             else if( !nRunByte )
34945fd3b9aSArmin Le Grand             {
35045fd3b9aSArmin Le Grand                 nY--;
35145fd3b9aSArmin Le Grand                 nX = 0UL;
35245fd3b9aSArmin Le Grand             }
35345fd3b9aSArmin Le Grand             else if( nRunByte == 1 )
35445fd3b9aSArmin Le Grand                 bEndDecoding = true;
35545fd3b9aSArmin Le Grand             else
35645fd3b9aSArmin Le Grand             {
35745fd3b9aSArmin Le Grand                 nX += *pRLE++;
35845fd3b9aSArmin Le Grand                 nY -= *pRLE++;
35945fd3b9aSArmin Le Grand             }
36045fd3b9aSArmin Le Grand         }
36145fd3b9aSArmin Le Grand         else
36245fd3b9aSArmin Le Grand         {
36345fd3b9aSArmin Le Grand             cTmp = *pRLE++;
36445fd3b9aSArmin Le Grand 
36545fd3b9aSArmin Le Grand             if( bRLE4 )
36645fd3b9aSArmin Le Grand             {
36745fd3b9aSArmin Le Grand                 nRunByte = nCountByte >> 1;
36845fd3b9aSArmin Le Grand 
36945fd3b9aSArmin Le Grand                 for( sal_uLong i = 0UL; i < nRunByte; i++ )
37045fd3b9aSArmin Le Grand                 {
37145fd3b9aSArmin Le Grand                     if( nX < nWidth )
37245fd3b9aSArmin Le Grand                         rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 );
37345fd3b9aSArmin Le Grand 
37445fd3b9aSArmin Le Grand                     if( nX < nWidth )
37545fd3b9aSArmin Le Grand                         rAcc.SetPixelIndex( nY, nX++, cTmp & 0x0f );
37645fd3b9aSArmin Le Grand                 }
37745fd3b9aSArmin Le Grand 
37845fd3b9aSArmin Le Grand                 if( ( nCountByte & 1 ) && ( nX < nWidth ) )
37945fd3b9aSArmin Le Grand                     rAcc.SetPixelIndex( nY, nX++, cTmp >> 4 );
38045fd3b9aSArmin Le Grand             }
38145fd3b9aSArmin Le Grand             else
38245fd3b9aSArmin Le Grand             {
38345fd3b9aSArmin Le Grand                 for( sal_uLong i = 0UL; ( i < nCountByte ) && ( nX < nWidth ); i++ )
38445fd3b9aSArmin Le Grand                     rAcc.SetPixelIndex( nY, nX++, cTmp );
38545fd3b9aSArmin Le Grand             }
38645fd3b9aSArmin Le Grand         }
38745fd3b9aSArmin Le Grand     }
38845fd3b9aSArmin Le Grand     while ( !bEndDecoding && ( nY >= 0L ) );
38945fd3b9aSArmin Le Grand }
39045fd3b9aSArmin Le Grand 
ImplReadDIBBits(SvStream & rIStm,DIBV5Header & rHeader,BitmapWriteAccess & rAcc,BitmapWriteAccess * pAccAlpha,bool bTopDown,bool & rAlphaUsed)391c7a371deSArmin Le Grand bool ImplReadDIBBits(SvStream& rIStm, DIBV5Header& rHeader, BitmapWriteAccess& rAcc, BitmapWriteAccess* pAccAlpha, bool bTopDown, bool& rAlphaUsed)
39245fd3b9aSArmin Le Grand {
39318c07a55SJürgen Schmidt     const sal_Int64 nBitsPerLine (static_cast<sal_Int64>(rHeader.nWidth) * static_cast<sal_Int64>(rHeader.nBitCount));
39418c07a55SJürgen Schmidt     if (nBitsPerLine > SAL_MAX_UINT32)
39518c07a55SJürgen Schmidt         return false;
39618c07a55SJürgen Schmidt 
39718c07a55SJürgen Schmidt     const sal_uLong nAlignedWidth = AlignedWidth4Bytes(static_cast<sal_uLong>(nBitsPerLine));
398c7a371deSArmin Le Grand     sal_uInt32 nRMask(( rHeader.nBitCount == 16 ) ? 0x00007c00UL : 0x00ff0000UL);
399c7a371deSArmin Le Grand     sal_uInt32 nGMask(( rHeader.nBitCount == 16 ) ? 0x000003e0UL : 0x0000ff00UL);
400c7a371deSArmin Le Grand     sal_uInt32 nBMask(( rHeader.nBitCount == 16 ) ? 0x0000001fUL : 0x000000ffUL);
40145fd3b9aSArmin Le Grand     bool bNative(false);
40245fd3b9aSArmin Le Grand     bool bTCMask(!pAccAlpha && ((16 == rHeader.nBitCount) || (32 == rHeader.nBitCount)));
40345fd3b9aSArmin Le Grand     bool bRLE((RLE_8 == rHeader.nCompression && 8 == rHeader.nBitCount) || (RLE_4 == rHeader.nCompression && 4 == rHeader.nBitCount));
40445fd3b9aSArmin Le Grand 
40545fd3b9aSArmin Le Grand     // Is native format?
40645fd3b9aSArmin Le Grand     switch(rAcc.GetScanlineFormat())
40745fd3b9aSArmin Le Grand     {
40845fd3b9aSArmin Le Grand         case( BMP_FORMAT_1BIT_MSB_PAL ):
40945fd3b9aSArmin Le Grand         case( BMP_FORMAT_4BIT_MSN_PAL ):
41045fd3b9aSArmin Le Grand         case( BMP_FORMAT_8BIT_PAL ):
41145fd3b9aSArmin Le Grand         case( BMP_FORMAT_24BIT_TC_BGR ):
41245fd3b9aSArmin Le Grand         {
41345fd3b9aSArmin Le Grand             bNative = ( ( static_cast< bool >(rAcc.IsBottomUp()) != bTopDown ) && !bRLE && !bTCMask && ( rAcc.GetScanlineSize() == nAlignedWidth ) );
41445fd3b9aSArmin Le Grand             break;
41545fd3b9aSArmin Le Grand         }
41645fd3b9aSArmin Le Grand 
41745fd3b9aSArmin Le Grand         default:
41845fd3b9aSArmin Le Grand         {
41945fd3b9aSArmin Le Grand             break;
42045fd3b9aSArmin Le Grand         }
42145fd3b9aSArmin Le Grand     }
42245fd3b9aSArmin Le Grand 
42345fd3b9aSArmin Le Grand     // Read data
42445fd3b9aSArmin Le Grand     if(bNative)
42545fd3b9aSArmin Le Grand     {
42645fd3b9aSArmin Le Grand         rIStm.Read(rAcc.GetBuffer(), rHeader.nHeight * nAlignedWidth);
42745fd3b9aSArmin Le Grand     }
42845fd3b9aSArmin Le Grand     else
42945fd3b9aSArmin Le Grand     {
43045fd3b9aSArmin Le Grand         // Read color mask
431c7a371deSArmin Le Grand         if(bTCMask && BITFIELDS == rHeader.nCompression)
43245fd3b9aSArmin Le Grand         {
43345fd3b9aSArmin Le Grand             rIStm.SeekRel( -12L );
43445fd3b9aSArmin Le Grand             rIStm >> nRMask;
43545fd3b9aSArmin Le Grand             rIStm >> nGMask;
43645fd3b9aSArmin Le Grand             rIStm >> nBMask;
43745fd3b9aSArmin Le Grand         }
43845fd3b9aSArmin Le Grand 
43945fd3b9aSArmin Le Grand         if(bRLE)
44045fd3b9aSArmin Le Grand         {
44145fd3b9aSArmin Le Grand             if(!rHeader.nSizeImage)
44245fd3b9aSArmin Le Grand             {
44345fd3b9aSArmin Le Grand                 const sal_uLong nOldPos(rIStm.Tell());
44445fd3b9aSArmin Le Grand 
44545fd3b9aSArmin Le Grand                 rIStm.Seek(STREAM_SEEK_TO_END);
44645fd3b9aSArmin Le Grand                 rHeader.nSizeImage = rIStm.Tell() - nOldPos;
44745fd3b9aSArmin Le Grand                 rIStm.Seek(nOldPos);
44845fd3b9aSArmin Le Grand             }
44945fd3b9aSArmin Le Grand 
45045fd3b9aSArmin Le Grand             sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(rHeader.nSizeImage);
45145fd3b9aSArmin Le Grand             rIStm.Read((char*)pBuffer, rHeader.nSizeImage);
45245fd3b9aSArmin Le Grand             ImplDecodeRLE(pBuffer, rHeader, rAcc, RLE_4 == rHeader.nCompression);
45345fd3b9aSArmin Le Grand             rtl_freeMemory(pBuffer);
45445fd3b9aSArmin Le Grand         }
45545fd3b9aSArmin Le Grand         else
45645fd3b9aSArmin Le Grand         {
45745fd3b9aSArmin Le Grand             const long nWidth(rHeader.nWidth);
45845fd3b9aSArmin Le Grand             const long nHeight(rHeader.nHeight);
45945fd3b9aSArmin Le Grand             sal_uInt8* pBuf = new sal_uInt8[nAlignedWidth];
46045fd3b9aSArmin Le Grand 
46145fd3b9aSArmin Le Grand             const long nI(bTopDown ? 1 : -1);
46245fd3b9aSArmin Le Grand             long nY(bTopDown ? 0 : nHeight - 1);
46345fd3b9aSArmin Le Grand             long nCount(nHeight);
46445fd3b9aSArmin Le Grand 
46545fd3b9aSArmin Le Grand             switch(rHeader.nBitCount)
46645fd3b9aSArmin Le Grand             {
46745fd3b9aSArmin Le Grand                 case( 1 ):
46845fd3b9aSArmin Le Grand                 {
46945fd3b9aSArmin Le Grand                     sal_uInt8*  pTmp;
47045fd3b9aSArmin Le Grand                     sal_uInt8   cTmp;
47145fd3b9aSArmin Le Grand 
47245fd3b9aSArmin Le Grand                     for( ; nCount--; nY += nI )
47345fd3b9aSArmin Le Grand                     {
47445fd3b9aSArmin Le Grand                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
47545fd3b9aSArmin Le Grand                         cTmp = *pTmp++;
47645fd3b9aSArmin Le Grand 
47745fd3b9aSArmin Le Grand                         for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
47845fd3b9aSArmin Le Grand                         {
47945fd3b9aSArmin Le Grand                             if( !nShift )
48045fd3b9aSArmin Le Grand                             {
48145fd3b9aSArmin Le Grand                                 nShift = 8L,
48245fd3b9aSArmin Le Grand                                 cTmp = *pTmp++;
48345fd3b9aSArmin Le Grand                             }
48445fd3b9aSArmin Le Grand 
48545fd3b9aSArmin Le Grand                             rAcc.SetPixelIndex( nY, nX, (cTmp >> --nShift) & 1);
48645fd3b9aSArmin Le Grand                         }
48745fd3b9aSArmin Le Grand                     }
48845fd3b9aSArmin Le Grand                 }
48945fd3b9aSArmin Le Grand                 break;
49045fd3b9aSArmin Le Grand 
49145fd3b9aSArmin Le Grand                 case( 4 ):
49245fd3b9aSArmin Le Grand                 {
49345fd3b9aSArmin Le Grand                     sal_uInt8*  pTmp;
49445fd3b9aSArmin Le Grand                     sal_uInt8   cTmp;
49545fd3b9aSArmin Le Grand 
49645fd3b9aSArmin Le Grand                     for( ; nCount--; nY += nI )
49745fd3b9aSArmin Le Grand                     {
49845fd3b9aSArmin Le Grand                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
49945fd3b9aSArmin Le Grand                         cTmp = *pTmp++;
50045fd3b9aSArmin Le Grand 
50145fd3b9aSArmin Le Grand                         for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
50245fd3b9aSArmin Le Grand                         {
50345fd3b9aSArmin Le Grand                             if( !nShift )
50445fd3b9aSArmin Le Grand                             {
50545fd3b9aSArmin Le Grand                                 nShift = 2UL,
50645fd3b9aSArmin Le Grand                                 cTmp = *pTmp++;
50745fd3b9aSArmin Le Grand                             }
50845fd3b9aSArmin Le Grand 
50945fd3b9aSArmin Le Grand                             rAcc.SetPixelIndex( nY, nX, (cTmp >> ( --nShift << 2UL ) ) & 0x0f);
51045fd3b9aSArmin Le Grand                         }
51145fd3b9aSArmin Le Grand                     }
51245fd3b9aSArmin Le Grand                 }
51345fd3b9aSArmin Le Grand                 break;
51445fd3b9aSArmin Le Grand 
51545fd3b9aSArmin Le Grand                 case( 8 ):
51645fd3b9aSArmin Le Grand                 {
51745fd3b9aSArmin Le Grand                     sal_uInt8*  pTmp;
51845fd3b9aSArmin Le Grand 
51945fd3b9aSArmin Le Grand                     for( ; nCount--; nY += nI )
52045fd3b9aSArmin Le Grand                     {
52145fd3b9aSArmin Le Grand                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
52245fd3b9aSArmin Le Grand 
52345fd3b9aSArmin Le Grand                         for( long nX = 0L; nX < nWidth; nX++ )
52445fd3b9aSArmin Le Grand                             rAcc.SetPixelIndex( nY, nX, *pTmp++ );
52545fd3b9aSArmin Le Grand                     }
52645fd3b9aSArmin Le Grand                 }
52745fd3b9aSArmin Le Grand                 break;
52845fd3b9aSArmin Le Grand 
52945fd3b9aSArmin Le Grand                 case( 16 ):
53045fd3b9aSArmin Le Grand                 {
53145fd3b9aSArmin Le Grand                     ColorMask   aMask( nRMask, nGMask, nBMask );
53245fd3b9aSArmin Le Grand                     BitmapColor aColor;
53345fd3b9aSArmin Le Grand                     sal_uInt16*     pTmp16;
53445fd3b9aSArmin Le Grand 
53545fd3b9aSArmin Le Grand                     for( ; nCount--; nY += nI )
53645fd3b9aSArmin Le Grand                     {
53745fd3b9aSArmin Le Grand                         rIStm.Read( (char*)( pTmp16 = (sal_uInt16*) pBuf ), nAlignedWidth );
53845fd3b9aSArmin Le Grand 
53945fd3b9aSArmin Le Grand                         for( long nX = 0L; nX < nWidth; nX++ )
54045fd3b9aSArmin Le Grand                         {
54145fd3b9aSArmin Le Grand                             aMask.GetColorFor16BitLSB( aColor, (sal_uInt8*) pTmp16++ );
54245fd3b9aSArmin Le Grand                             rAcc.SetPixel( nY, nX, aColor );
54345fd3b9aSArmin Le Grand                         }
54445fd3b9aSArmin Le Grand                     }
54545fd3b9aSArmin Le Grand                 }
54645fd3b9aSArmin Le Grand                 break;
54745fd3b9aSArmin Le Grand 
54845fd3b9aSArmin Le Grand                 case( 24 ):
54945fd3b9aSArmin Le Grand                 {
55045fd3b9aSArmin Le Grand                     BitmapColor aPixelColor;
55145fd3b9aSArmin Le Grand                     sal_uInt8*      pTmp;
55245fd3b9aSArmin Le Grand 
55345fd3b9aSArmin Le Grand                     for( ; nCount--; nY += nI )
55445fd3b9aSArmin Le Grand                     {
55545fd3b9aSArmin Le Grand                         rIStm.Read( pTmp = pBuf, nAlignedWidth );
55645fd3b9aSArmin Le Grand 
55745fd3b9aSArmin Le Grand                         for( long nX = 0L; nX < nWidth; nX++ )
55845fd3b9aSArmin Le Grand                         {
55945fd3b9aSArmin Le Grand                             aPixelColor.SetBlue( *pTmp++ );
56045fd3b9aSArmin Le Grand                             aPixelColor.SetGreen( *pTmp++ );
56145fd3b9aSArmin Le Grand                             aPixelColor.SetRed( *pTmp++ );
56245fd3b9aSArmin Le Grand                             rAcc.SetPixel( nY, nX, aPixelColor );
56345fd3b9aSArmin Le Grand                         }
56445fd3b9aSArmin Le Grand                     }
56545fd3b9aSArmin Le Grand                 }
56645fd3b9aSArmin Le Grand                 break;
56745fd3b9aSArmin Le Grand 
56845fd3b9aSArmin Le Grand                 case( 32 ):
56945fd3b9aSArmin Le Grand                 {
57045fd3b9aSArmin Le Grand                     ColorMask aMask(nRMask, nGMask, nBMask);
57145fd3b9aSArmin Le Grand                     BitmapColor aColor;
57245fd3b9aSArmin Le Grand                     sal_uInt32* pTmp32;
57345fd3b9aSArmin Le Grand 
57445fd3b9aSArmin Le Grand                     if(pAccAlpha)
57545fd3b9aSArmin Le Grand                     {
57645fd3b9aSArmin Le Grand                         sal_uInt8 aAlpha;
57745fd3b9aSArmin Le Grand 
57845fd3b9aSArmin Le Grand                         for( ; nCount--; nY += nI )
57945fd3b9aSArmin Le Grand                         {
58045fd3b9aSArmin Le Grand                             rIStm.Read( (char*)( pTmp32 = (sal_uInt32*) pBuf ), nAlignedWidth );
58145fd3b9aSArmin Le Grand 
58245fd3b9aSArmin Le Grand                             for( long nX = 0L; nX < nWidth; nX++ )
58345fd3b9aSArmin Le Grand                             {
58445fd3b9aSArmin Le Grand                                 aMask.GetColorAndAlphaFor32Bit( aColor, aAlpha, (sal_uInt8*) pTmp32++ );
58545fd3b9aSArmin Le Grand                                 rAcc.SetPixel( nY, nX, aColor );
58645fd3b9aSArmin Le Grand                                 pAccAlpha->SetPixelIndex(nY, nX, sal_uInt8(0xff) - aAlpha);
587c7a371deSArmin Le Grand                                 rAlphaUsed |= bool(0xff != aAlpha);
58845fd3b9aSArmin Le Grand                             }
58945fd3b9aSArmin Le Grand                         }
59045fd3b9aSArmin Le Grand                     }
59145fd3b9aSArmin Le Grand                     else
59245fd3b9aSArmin Le Grand                     {
59345fd3b9aSArmin Le Grand                         for( ; nCount--; nY += nI )
59445fd3b9aSArmin Le Grand                         {
59545fd3b9aSArmin Le Grand                             rIStm.Read( (char*)( pTmp32 = (sal_uInt32*) pBuf ), nAlignedWidth );
59645fd3b9aSArmin Le Grand 
59745fd3b9aSArmin Le Grand                             for( long nX = 0L; nX < nWidth; nX++ )
59845fd3b9aSArmin Le Grand                             {
59945fd3b9aSArmin Le Grand                                 aMask.GetColorFor32Bit( aColor, (sal_uInt8*) pTmp32++ );
60045fd3b9aSArmin Le Grand                                 rAcc.SetPixel( nY, nX, aColor );
60145fd3b9aSArmin Le Grand                             }
60245fd3b9aSArmin Le Grand                         }
60345fd3b9aSArmin Le Grand                     }
60445fd3b9aSArmin Le Grand                 }
60545fd3b9aSArmin Le Grand             }
60645fd3b9aSArmin Le Grand 
60745fd3b9aSArmin Le Grand             delete[] pBuf;
60845fd3b9aSArmin Le Grand         }
60945fd3b9aSArmin Le Grand     }
61045fd3b9aSArmin Le Grand 
61145fd3b9aSArmin Le Grand     return( rIStm.GetError() == 0UL );
61245fd3b9aSArmin Le Grand }
61345fd3b9aSArmin Le Grand 
ImplReadDIBBody(SvStream & rIStm,Bitmap & rBmp,Bitmap * pBmpAlpha,sal_uLong nOffset)61445fd3b9aSArmin Le Grand bool ImplReadDIBBody( SvStream& rIStm, Bitmap& rBmp, Bitmap* pBmpAlpha, sal_uLong nOffset )
61545fd3b9aSArmin Le Grand {
61645fd3b9aSArmin Le Grand     DIBV5Header aHeader;
61745fd3b9aSArmin Le Grand     const sal_uLong nStmPos = rIStm.Tell();
61845fd3b9aSArmin Le Grand     bool bRet( false );
61945fd3b9aSArmin Le Grand     bool bTopDown( false );
62045fd3b9aSArmin Le Grand 
621*6e7df57eSOliver-Rainer Wittmann     if ( ImplReadDIBInfoHeader( rIStm, aHeader, bTopDown )
622*6e7df57eSOliver-Rainer Wittmann          && aHeader.nWidth != 0
623*6e7df57eSOliver-Rainer Wittmann          && aHeader.nHeight != 0
624*6e7df57eSOliver-Rainer Wittmann          && aHeader.nBitCount != 0 )
62545fd3b9aSArmin Le Grand     {
626*6e7df57eSOliver-Rainer Wittmann         if ( nOffset > 0 && aHeader.nSize > nOffset )
62718c07a55SJürgen Schmidt         {
62818c07a55SJürgen Schmidt             // Header size claims to extend into the image data.
62918c07a55SJürgen Schmidt             // Looks like an error.
63018c07a55SJürgen Schmidt             return false;
63118c07a55SJürgen Schmidt         }
63218c07a55SJürgen Schmidt 
63345fd3b9aSArmin Le Grand         const sal_uInt16 nBitCount(discretizeBitcount(aHeader.nBitCount));
63445fd3b9aSArmin Le Grand         const Size aSizePixel(aHeader.nWidth, aHeader.nHeight);
63545fd3b9aSArmin Le Grand         BitmapPalette aDummyPal;
63645fd3b9aSArmin Le Grand         Bitmap aNewBmp(aSizePixel, nBitCount, &aDummyPal);
63745fd3b9aSArmin Le Grand         Bitmap aNewBmpAlpha;
63845fd3b9aSArmin Le Grand         BitmapWriteAccess* pAcc = aNewBmp.AcquireWriteAccess();
63945fd3b9aSArmin Le Grand         BitmapWriteAccess* pAccAlpha = 0;
64045fd3b9aSArmin Le Grand         bool bAlphaPossible(pBmpAlpha && aHeader.nBitCount == 32);
64145fd3b9aSArmin Le Grand 
64245fd3b9aSArmin Le Grand         if(bAlphaPossible)
64345fd3b9aSArmin Le Grand         {
64445fd3b9aSArmin Le Grand             const bool bRedSet(0 != aHeader.nV5RedMask);
64545fd3b9aSArmin Le Grand             const bool bGreenSet(0 != aHeader.nV5GreenMask);
64645fd3b9aSArmin Le Grand             const bool bBlueSet(0 != aHeader.nV5BlueMask);
64745fd3b9aSArmin Le Grand 
64845fd3b9aSArmin Le Grand             // some clipboard entries have alpha mask on zero to say that there is
64945fd3b9aSArmin Le Grand             // no alpha; do only use this when the other masks are set. The MS docu
65045fd3b9aSArmin Le Grand             // says that that masks are only to be set when bV5Compression is set to
65145fd3b9aSArmin Le Grand             // BI_BITFIELDS, but there seem to exist a wild variety of usages...
65245fd3b9aSArmin Le Grand             if((bRedSet || bGreenSet || bBlueSet) && (0 == aHeader.nV5AlphaMask))
65345fd3b9aSArmin Le Grand             {
65445fd3b9aSArmin Le Grand                 bAlphaPossible = false;
65545fd3b9aSArmin Le Grand             }
65645fd3b9aSArmin Le Grand         }
65745fd3b9aSArmin Le Grand 
65845fd3b9aSArmin Le Grand         if(bAlphaPossible)
65945fd3b9aSArmin Le Grand         {
66045fd3b9aSArmin Le Grand             aNewBmpAlpha = Bitmap(aSizePixel, 8);
66145fd3b9aSArmin Le Grand             pAccAlpha = aNewBmpAlpha.AcquireWriteAccess();
66245fd3b9aSArmin Le Grand         }
66345fd3b9aSArmin Le Grand 
66445fd3b9aSArmin Le Grand         if(pAcc)
66545fd3b9aSArmin Le Grand         {
66645fd3b9aSArmin Le Grand             sal_uInt16 nColors(0);
66745fd3b9aSArmin Le Grand             SvStream* pIStm;
66845fd3b9aSArmin Le Grand             SvMemoryStream* pMemStm = NULL;
66945fd3b9aSArmin Le Grand             sal_uInt8* pData = NULL;
67045fd3b9aSArmin Le Grand 
67145fd3b9aSArmin Le Grand             if(nBitCount <= 8)
67245fd3b9aSArmin Le Grand             {
67345fd3b9aSArmin Le Grand                 if(aHeader.nColsUsed)
67445fd3b9aSArmin Le Grand                 {
67545fd3b9aSArmin Le Grand                     nColors = (sal_uInt16)aHeader.nColsUsed;
67645fd3b9aSArmin Le Grand                 }
67745fd3b9aSArmin Le Grand                 else
67845fd3b9aSArmin Le Grand                 {
67945fd3b9aSArmin Le Grand                     nColors = ( 1 << aHeader.nBitCount );
68045fd3b9aSArmin Le Grand                 }
68145fd3b9aSArmin Le Grand             }
68245fd3b9aSArmin Le Grand 
68345fd3b9aSArmin Le Grand             if(ZCOMPRESS == aHeader.nCompression)
68445fd3b9aSArmin Le Grand             {
68545fd3b9aSArmin Le Grand                 ZCodec aCodec;
68645fd3b9aSArmin Le Grand                 sal_uInt32 nCodedSize(0);
68745fd3b9aSArmin Le Grand                 sal_uInt32  nUncodedSize(0);
68845fd3b9aSArmin Le Grand                 sal_uLong nCodedPos(0);
68945fd3b9aSArmin Le Grand 
69045fd3b9aSArmin Le Grand                 // read coding information
69145fd3b9aSArmin Le Grand                 rIStm >> nCodedSize >> nUncodedSize >> aHeader.nCompression;
69245fd3b9aSArmin Le Grand                 pData = (sal_uInt8*) rtl_allocateMemory( nUncodedSize );
69345fd3b9aSArmin Le Grand 
69445fd3b9aSArmin Le Grand                 // decode buffer
69545fd3b9aSArmin Le Grand                 nCodedPos = rIStm.Tell();
69645fd3b9aSArmin Le Grand                 aCodec.BeginCompression();
69745fd3b9aSArmin Le Grand                 aCodec.Read( rIStm, pData, nUncodedSize );
69845fd3b9aSArmin Le Grand                 aCodec.EndCompression();
69945fd3b9aSArmin Le Grand 
70045fd3b9aSArmin Le Grand                 // skip unread bytes from coded buffer
70145fd3b9aSArmin Le Grand                 rIStm.SeekRel( nCodedSize - ( rIStm.Tell() - nCodedPos ) );
70245fd3b9aSArmin Le Grand 
70345fd3b9aSArmin Le Grand                 // set decoded bytes to memory stream,
70445fd3b9aSArmin Le Grand                 // from which we will read the bitmap data
70545fd3b9aSArmin Le Grand                 pIStm = pMemStm = new SvMemoryStream;
70645fd3b9aSArmin Le Grand                 pMemStm->SetBuffer( (char*) pData, nUncodedSize, false, nUncodedSize );
70745fd3b9aSArmin Le Grand                 nOffset = 0;
70845fd3b9aSArmin Le Grand             }
70945fd3b9aSArmin Le Grand             else
71045fd3b9aSArmin Le Grand             {
71145fd3b9aSArmin Le Grand                 pIStm = &rIStm;
71245fd3b9aSArmin Le Grand             }
71345fd3b9aSArmin Le Grand 
71445fd3b9aSArmin Le Grand             // read palette
71545fd3b9aSArmin Le Grand             if(nColors)
71645fd3b9aSArmin Le Grand             {
71745fd3b9aSArmin Le Grand                 pAcc->SetPaletteEntryCount(nColors);
71845fd3b9aSArmin Le Grand                 ImplReadDIBPalette(*pIStm, *pAcc, aHeader.nSize != DIBCOREHEADERSIZE);
71945fd3b9aSArmin Le Grand             }
72045fd3b9aSArmin Le Grand 
72145fd3b9aSArmin Le Grand             // read bits
722c7a371deSArmin Le Grand             bool bAlphaUsed(false);
723c7a371deSArmin Le Grand 
72445fd3b9aSArmin Le Grand             if(!pIStm->GetError())
72545fd3b9aSArmin Le Grand             {
72645fd3b9aSArmin Le Grand                 if(nOffset)
72745fd3b9aSArmin Le Grand                 {
72845fd3b9aSArmin Le Grand                     pIStm->SeekRel(nOffset - (pIStm->Tell() - nStmPos));
72945fd3b9aSArmin Le Grand                 }
73045fd3b9aSArmin Le Grand 
731c7a371deSArmin Le Grand                 bRet = ImplReadDIBBits(*pIStm, aHeader, *pAcc, pAccAlpha, bTopDown, bAlphaUsed);
73245fd3b9aSArmin Le Grand 
73345fd3b9aSArmin Le Grand                 if(bRet && aHeader.nXPelsPerMeter && aHeader.nYPelsPerMeter)
73445fd3b9aSArmin Le Grand                 {
73545fd3b9aSArmin Le Grand                     MapMode aMapMode(
73645fd3b9aSArmin Le Grand                         MAP_MM,
73745fd3b9aSArmin Le Grand                         Point(),
73845fd3b9aSArmin Le Grand                         Fraction(1000, aHeader.nXPelsPerMeter),
73945fd3b9aSArmin Le Grand                         Fraction(1000, aHeader.nYPelsPerMeter));
74045fd3b9aSArmin Le Grand 
74145fd3b9aSArmin Le Grand                     aNewBmp.SetPrefMapMode(aMapMode);
74245fd3b9aSArmin Le Grand                     aNewBmp.SetPrefSize(Size(aHeader.nWidth, aHeader.nHeight));
74345fd3b9aSArmin Le Grand                 }
74445fd3b9aSArmin Le Grand             }
74545fd3b9aSArmin Le Grand 
74645fd3b9aSArmin Le Grand             if( pData )
74745fd3b9aSArmin Le Grand             {
74845fd3b9aSArmin Le Grand                 rtl_freeMemory(pData);
74945fd3b9aSArmin Le Grand             }
75045fd3b9aSArmin Le Grand 
75145fd3b9aSArmin Le Grand             delete pMemStm;
75245fd3b9aSArmin Le Grand             aNewBmp.ReleaseAccess(pAcc);
75345fd3b9aSArmin Le Grand 
75445fd3b9aSArmin Le Grand             if(bAlphaPossible)
75545fd3b9aSArmin Le Grand             {
75645fd3b9aSArmin Le Grand                 aNewBmpAlpha.ReleaseAccess(pAccAlpha);
757c7a371deSArmin Le Grand 
758c7a371deSArmin Le Grand                 if(!bAlphaUsed)
759c7a371deSArmin Le Grand                 {
760c7a371deSArmin Le Grand                     bAlphaPossible = false;
761c7a371deSArmin Le Grand                 }
76245fd3b9aSArmin Le Grand             }
76345fd3b9aSArmin Le Grand 
76445fd3b9aSArmin Le Grand             if(bRet)
76545fd3b9aSArmin Le Grand             {
76645fd3b9aSArmin Le Grand                 rBmp = aNewBmp;
76745fd3b9aSArmin Le Grand 
76845fd3b9aSArmin Le Grand                 if(bAlphaPossible)
76945fd3b9aSArmin Le Grand                 {
77045fd3b9aSArmin Le Grand                     *pBmpAlpha = aNewBmpAlpha;
77145fd3b9aSArmin Le Grand                 }
77245fd3b9aSArmin Le Grand             }
77345fd3b9aSArmin Le Grand         }
77445fd3b9aSArmin Le Grand     }
77545fd3b9aSArmin Le Grand 
77645fd3b9aSArmin Le Grand     return bRet;
77745fd3b9aSArmin Le Grand }
77845fd3b9aSArmin Le Grand 
ImplReadDIBFileHeader(SvStream & rIStm,sal_uLong & rOffset)77945fd3b9aSArmin Le Grand bool ImplReadDIBFileHeader( SvStream& rIStm, sal_uLong& rOffset )
78045fd3b9aSArmin Le Grand {
78145fd3b9aSArmin Le Grand     bool bRet = false;
78245fd3b9aSArmin Le Grand 
78317c61744SOliver-Rainer Wittmann     const sal_Int64 nSavedStreamPos( rIStm.Tell() );
78418c07a55SJürgen Schmidt     const sal_Int64 nStreamLength( rIStm.Seek( STREAM_SEEK_TO_END ) );
78517c61744SOliver-Rainer Wittmann     rIStm.Seek( nSavedStreamPos );
78618c07a55SJürgen Schmidt 
78717c61744SOliver-Rainer Wittmann     sal_uInt16 nTmp16 = 0;
78845fd3b9aSArmin Le Grand     rIStm >> nTmp16;
78945fd3b9aSArmin Le Grand 
79045fd3b9aSArmin Le Grand     if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) )
79145fd3b9aSArmin Le Grand     {
79217c61744SOliver-Rainer Wittmann         sal_uInt32 nTmp32;
79345fd3b9aSArmin Le Grand         if ( 0x4142 == nTmp16 )
79445fd3b9aSArmin Le Grand         {
79545fd3b9aSArmin Le Grand             rIStm.SeekRel( 12L );
79645fd3b9aSArmin Le Grand             rIStm >> nTmp16;
79745fd3b9aSArmin Le Grand             rIStm.SeekRel( 8L );
79845fd3b9aSArmin Le Grand             rIStm >> nTmp32;
79945fd3b9aSArmin Le Grand             rOffset = nTmp32 - 28UL;
80045fd3b9aSArmin Le Grand             bRet = ( 0x4D42 == nTmp16 );
80145fd3b9aSArmin Le Grand         }
80245fd3b9aSArmin Le Grand         else // 0x4D42 == nTmp16, 'MB' from BITMAPFILEHEADER
80345fd3b9aSArmin Le Grand         {
80445fd3b9aSArmin Le Grand             rIStm.SeekRel( 8L );        // we are on bfSize member of BITMAPFILEHEADER, forward to bfOffBits
80545fd3b9aSArmin Le Grand             rIStm >> nTmp32;            // read bfOffBits
80645fd3b9aSArmin Le Grand             rOffset = nTmp32 - 14UL;    // adapt offset by sizeof(BITMAPFILEHEADER)
80745fd3b9aSArmin Le Grand             bRet = ( rIStm.GetError() == 0UL );
80845fd3b9aSArmin Le Grand         }
80918c07a55SJürgen Schmidt 
81018c07a55SJürgen Schmidt         if ( rOffset >= nStreamLength )
81118c07a55SJürgen Schmidt         {
81218c07a55SJürgen Schmidt             // Offset claims that image starts past the end of the
81318c07a55SJürgen Schmidt             // stream.  Unlikely.
81418c07a55SJürgen Schmidt             rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
81518c07a55SJürgen Schmidt             bRet = false;
81618c07a55SJürgen Schmidt         }
81745fd3b9aSArmin Le Grand     }
81845fd3b9aSArmin Le Grand     else
81945fd3b9aSArmin Le Grand         rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
82045fd3b9aSArmin Le Grand 
82145fd3b9aSArmin Le Grand     return bRet;
82245fd3b9aSArmin Le Grand }
82345fd3b9aSArmin Le Grand 
ImplWriteDIBPalette(SvStream & rOStm,BitmapReadAccess & rAcc)82445fd3b9aSArmin Le Grand bool ImplWriteDIBPalette( SvStream& rOStm, BitmapReadAccess& rAcc )
82545fd3b9aSArmin Le Grand {
82645fd3b9aSArmin Le Grand     const sal_uInt16    nColors = rAcc.GetPaletteEntryCount();
82745fd3b9aSArmin Le Grand     const sal_uLong     nPalSize = nColors * 4UL;
82845fd3b9aSArmin Le Grand     sal_uInt8*          pEntries = new sal_uInt8[ nPalSize ];
82945fd3b9aSArmin Le Grand     sal_uInt8*          pTmpEntry = pEntries;
83045fd3b9aSArmin Le Grand     BitmapColor     aPalColor;
83145fd3b9aSArmin Le Grand 
83245fd3b9aSArmin Le Grand     for( sal_uInt16 i = 0; i < nColors; i++ )
83345fd3b9aSArmin Le Grand     {
83445fd3b9aSArmin Le Grand         const BitmapColor& rPalColor = rAcc.GetPaletteColor( i );
83545fd3b9aSArmin Le Grand 
83645fd3b9aSArmin Le Grand         *pTmpEntry++ = rPalColor.GetBlue();
83745fd3b9aSArmin Le Grand         *pTmpEntry++ = rPalColor.GetGreen();
83845fd3b9aSArmin Le Grand         *pTmpEntry++ = rPalColor.GetRed();
83945fd3b9aSArmin Le Grand         *pTmpEntry++ = 0;
84045fd3b9aSArmin Le Grand     }
84145fd3b9aSArmin Le Grand 
84245fd3b9aSArmin Le Grand     rOStm.Write( pEntries, nPalSize );
84345fd3b9aSArmin Le Grand     delete[] pEntries;
84445fd3b9aSArmin Le Grand 
84545fd3b9aSArmin Le Grand     return( rOStm.GetError() == 0UL );
84645fd3b9aSArmin Le Grand }
84745fd3b9aSArmin Le Grand 
ImplWriteRLE(SvStream & rOStm,BitmapReadAccess & rAcc,bool bRLE4)84845fd3b9aSArmin Le Grand bool ImplWriteRLE( SvStream& rOStm, BitmapReadAccess& rAcc, bool bRLE4 )
84945fd3b9aSArmin Le Grand {
85045fd3b9aSArmin Le Grand     const sal_uLong nWidth = rAcc.Width();
85145fd3b9aSArmin Le Grand     const sal_uLong nHeight = rAcc.Height();
85245fd3b9aSArmin Le Grand     sal_uLong       nX;
85345fd3b9aSArmin Le Grand     sal_uLong       nSaveIndex;
85445fd3b9aSArmin Le Grand     sal_uLong       nCount;
85545fd3b9aSArmin Le Grand     sal_uLong       nBufCount;
85645fd3b9aSArmin Le Grand     sal_uInt8*      pBuf = new sal_uInt8[ ( nWidth << 1 ) + 2 ];
85745fd3b9aSArmin Le Grand     sal_uInt8*      pTmp;
85845fd3b9aSArmin Le Grand     sal_uInt8       cPix;
85945fd3b9aSArmin Le Grand     sal_uInt8       cLast;
86045fd3b9aSArmin Le Grand     bool        bFound;
86145fd3b9aSArmin Le Grand 
86245fd3b9aSArmin Le Grand     for ( long nY = nHeight - 1L; nY >= 0L; nY-- )
86345fd3b9aSArmin Le Grand     {
86445fd3b9aSArmin Le Grand         pTmp = pBuf;
86545fd3b9aSArmin Le Grand         nX = nBufCount = 0UL;
86645fd3b9aSArmin Le Grand 
86745fd3b9aSArmin Le Grand         while( nX < nWidth )
86845fd3b9aSArmin Le Grand         {
86945fd3b9aSArmin Le Grand             nCount = 1L;
87045fd3b9aSArmin Le Grand             cPix = rAcc.GetPixelIndex( nY, nX++ );
87145fd3b9aSArmin Le Grand 
87245fd3b9aSArmin Le Grand             while( ( nX < nWidth ) && ( nCount < 255L )
87345fd3b9aSArmin Le Grand                 && ( cPix == rAcc.GetPixelIndex( nY, nX ) ) )
87445fd3b9aSArmin Le Grand             {
87545fd3b9aSArmin Le Grand                 nX++;
87645fd3b9aSArmin Le Grand                 nCount++;
87745fd3b9aSArmin Le Grand             }
87845fd3b9aSArmin Le Grand 
87945fd3b9aSArmin Le Grand             if ( nCount > 1 )
88045fd3b9aSArmin Le Grand             {
88145fd3b9aSArmin Le Grand                 *pTmp++ = (sal_uInt8) nCount;
88245fd3b9aSArmin Le Grand                 *pTmp++ = ( bRLE4 ? ( ( cPix << 4 ) | cPix ) : cPix );
88345fd3b9aSArmin Le Grand                 nBufCount += 2;
88445fd3b9aSArmin Le Grand             }
88545fd3b9aSArmin Le Grand             else
88645fd3b9aSArmin Le Grand             {
88745fd3b9aSArmin Le Grand                 cLast = cPix;
88845fd3b9aSArmin Le Grand                 nSaveIndex = nX - 1UL;
88945fd3b9aSArmin Le Grand                 bFound = false;
89045fd3b9aSArmin Le Grand 
89145fd3b9aSArmin Le Grand                 while( ( nX < nWidth ) && ( nCount < 256L )
89245fd3b9aSArmin Le Grand                     && ( cPix = rAcc.GetPixelIndex( nY, nX ) ) != cLast )
89345fd3b9aSArmin Le Grand                 {
89445fd3b9aSArmin Le Grand                     nX++; nCount++;
89545fd3b9aSArmin Le Grand                     cLast = cPix;
89645fd3b9aSArmin Le Grand                     bFound = true;
89745fd3b9aSArmin Le Grand                 }
89845fd3b9aSArmin Le Grand 
89945fd3b9aSArmin Le Grand                 if ( bFound )
90045fd3b9aSArmin Le Grand                     nX--;
90145fd3b9aSArmin Le Grand 
90245fd3b9aSArmin Le Grand                 if ( nCount > 3 )
90345fd3b9aSArmin Le Grand                 {
90445fd3b9aSArmin Le Grand                     *pTmp++ = 0;
90545fd3b9aSArmin Le Grand                     *pTmp++ = (sal_uInt8) --nCount;
90645fd3b9aSArmin Le Grand 
90745fd3b9aSArmin Le Grand                     if( bRLE4 )
90845fd3b9aSArmin Le Grand                     {
90945fd3b9aSArmin Le Grand                         for ( sal_uLong i = 0; i < nCount; i++, pTmp++ )
91045fd3b9aSArmin Le Grand                         {
91145fd3b9aSArmin Le Grand                             *pTmp = rAcc.GetPixelIndex( nY, nSaveIndex++ ) << 4;
91245fd3b9aSArmin Le Grand 
91345fd3b9aSArmin Le Grand                             if ( ++i < nCount )
91445fd3b9aSArmin Le Grand                                 *pTmp |= rAcc.GetPixelIndex( nY, nSaveIndex++ );
91545fd3b9aSArmin Le Grand                         }
91645fd3b9aSArmin Le Grand 
91745fd3b9aSArmin Le Grand                         nCount = ( nCount + 1 ) >> 1;
91845fd3b9aSArmin Le Grand                     }
91945fd3b9aSArmin Le Grand                     else
92045fd3b9aSArmin Le Grand                     {
92145fd3b9aSArmin Le Grand                         for( sal_uLong i = 0UL; i < nCount; i++ )
92245fd3b9aSArmin Le Grand                             *pTmp++ = rAcc.GetPixelIndex( nY, nSaveIndex++ );
92345fd3b9aSArmin Le Grand                     }
92445fd3b9aSArmin Le Grand 
92545fd3b9aSArmin Le Grand                     if ( nCount & 1 )
92645fd3b9aSArmin Le Grand                     {
92745fd3b9aSArmin Le Grand                         *pTmp++ = 0;
92845fd3b9aSArmin Le Grand                         nBufCount += ( nCount + 3 );
92945fd3b9aSArmin Le Grand                     }
93045fd3b9aSArmin Le Grand                     else
93145fd3b9aSArmin Le Grand                         nBufCount += ( nCount + 2 );
93245fd3b9aSArmin Le Grand                 }
93345fd3b9aSArmin Le Grand                 else
93445fd3b9aSArmin Le Grand                 {
93545fd3b9aSArmin Le Grand                     *pTmp++ = 1;
93645fd3b9aSArmin Le Grand                     *pTmp++ = rAcc.GetPixelIndex( nY, nSaveIndex ) << (bRLE4 ? 4 : 0);
93745fd3b9aSArmin Le Grand 
93845fd3b9aSArmin Le Grand                     if ( nCount == 3 )
93945fd3b9aSArmin Le Grand                     {
94045fd3b9aSArmin Le Grand                         *pTmp++ = 1;
94145fd3b9aSArmin Le Grand                         *pTmp++ = rAcc.GetPixelIndex( nY, ++nSaveIndex ) << ( bRLE4 ? 4 : 0 );
94245fd3b9aSArmin Le Grand                         nBufCount += 4;
94345fd3b9aSArmin Le Grand                     }
94445fd3b9aSArmin Le Grand                     else
94545fd3b9aSArmin Le Grand                         nBufCount += 2;
94645fd3b9aSArmin Le Grand                 }
94745fd3b9aSArmin Le Grand             }
94845fd3b9aSArmin Le Grand         }
94945fd3b9aSArmin Le Grand 
95045fd3b9aSArmin Le Grand         pBuf[ nBufCount++ ] = 0;
95145fd3b9aSArmin Le Grand         pBuf[ nBufCount++ ] = 0;
95245fd3b9aSArmin Le Grand 
95345fd3b9aSArmin Le Grand         rOStm.Write( pBuf, nBufCount );
95445fd3b9aSArmin Le Grand     }
95545fd3b9aSArmin Le Grand 
95645fd3b9aSArmin Le Grand     rOStm << (sal_uInt8) 0;
95745fd3b9aSArmin Le Grand     rOStm << (sal_uInt8) 1;
95845fd3b9aSArmin Le Grand 
95945fd3b9aSArmin Le Grand     delete[] pBuf;
96045fd3b9aSArmin Le Grand 
96145fd3b9aSArmin Le Grand     return( rOStm.GetError() == 0UL );
96245fd3b9aSArmin Le Grand }
96345fd3b9aSArmin Le Grand 
ImplWriteDIBBits(SvStream & rOStm,BitmapReadAccess & rAcc,BitmapReadAccess * pAccAlpha,sal_uLong nCompression,sal_uInt32 & rImageSize)96445fd3b9aSArmin Le Grand bool ImplWriteDIBBits(SvStream& rOStm, BitmapReadAccess& rAcc, BitmapReadAccess* pAccAlpha, sal_uLong nCompression, sal_uInt32& rImageSize)
96545fd3b9aSArmin Le Grand {
96645fd3b9aSArmin Le Grand     if(!pAccAlpha && BITFIELDS == nCompression)
96745fd3b9aSArmin Le Grand     {
96845fd3b9aSArmin Le Grand         const ColorMask&    rMask = rAcc.GetColorMask();
96945fd3b9aSArmin Le Grand         SVBT32              aVal32;
97045fd3b9aSArmin Le Grand 
97145fd3b9aSArmin Le Grand         UInt32ToSVBT32( rMask.GetRedMask(), aVal32 );
97245fd3b9aSArmin Le Grand         rOStm.Write( (sal_uInt8*) aVal32, 4UL );
97345fd3b9aSArmin Le Grand 
97445fd3b9aSArmin Le Grand         UInt32ToSVBT32( rMask.GetGreenMask(), aVal32 );
97545fd3b9aSArmin Le Grand         rOStm.Write( (sal_uInt8*) aVal32, 4UL );
97645fd3b9aSArmin Le Grand 
97745fd3b9aSArmin Le Grand         UInt32ToSVBT32( rMask.GetBlueMask(), aVal32 );
97845fd3b9aSArmin Le Grand         rOStm.Write( (sal_uInt8*) aVal32, 4UL );
97945fd3b9aSArmin Le Grand 
98045fd3b9aSArmin Le Grand         rImageSize = rOStm.Tell();
98145fd3b9aSArmin Le Grand 
98245fd3b9aSArmin Le Grand         if( rAcc.IsBottomUp() )
98345fd3b9aSArmin Le Grand             rOStm.Write( rAcc.GetBuffer(), rAcc.Height() * rAcc.GetScanlineSize() );
98445fd3b9aSArmin Le Grand         else
98545fd3b9aSArmin Le Grand         {
98645fd3b9aSArmin Le Grand             for( long nY = rAcc.Height() - 1, nScanlineSize = rAcc.GetScanlineSize(); nY >= 0L; nY-- )
98745fd3b9aSArmin Le Grand                 rOStm.Write( rAcc.GetScanline( nY ), nScanlineSize );
98845fd3b9aSArmin Le Grand         }
98945fd3b9aSArmin Le Grand     }
99045fd3b9aSArmin Le Grand     else if(!pAccAlpha && ((RLE_4 == nCompression) || (RLE_8 == nCompression)))
99145fd3b9aSArmin Le Grand     {
99245fd3b9aSArmin Le Grand         rImageSize = rOStm.Tell();
99345fd3b9aSArmin Le Grand         ImplWriteRLE( rOStm, rAcc, RLE_4 == nCompression );
99445fd3b9aSArmin Le Grand     }
99545fd3b9aSArmin Le Grand     else if(!nCompression)
99645fd3b9aSArmin Le Grand     {
99745fd3b9aSArmin Le Grand         // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are not
99845fd3b9aSArmin Le Grand         // handled properly below (would have to set color masks, and
99945fd3b9aSArmin Le Grand         // nCompression=BITFIELDS - but color mask is not set for
100045fd3b9aSArmin Le Grand         // formats != *_TC_*). Note that this very problem might cause
100145fd3b9aSArmin Le Grand         // trouble at other places - the introduction of 32 bit RGBA
100245fd3b9aSArmin Le Grand         // bitmaps is relatively recent.
100345fd3b9aSArmin Le Grand         // #i59239# discretize bitcount for aligned width to 1,4,8,24
100445fd3b9aSArmin Le Grand         // (other cases are not written below)
100545fd3b9aSArmin Le Grand         const sal_uInt16 nBitCount(pAccAlpha ? 32 : discretizeBitcount(static_cast< sal_uInt16 >(rAcc.GetBitCount())));
100645fd3b9aSArmin Le Grand         const sal_uLong nAlignedWidth(AlignedWidth4Bytes(rAcc.Width() * nBitCount));
100745fd3b9aSArmin Le Grand         bool bNative(false);
100845fd3b9aSArmin Le Grand 
100945fd3b9aSArmin Le Grand         switch(rAcc.GetScanlineFormat())
101045fd3b9aSArmin Le Grand         {
101145fd3b9aSArmin Le Grand             case( BMP_FORMAT_1BIT_MSB_PAL ):
101245fd3b9aSArmin Le Grand             case( BMP_FORMAT_4BIT_MSN_PAL ):
101345fd3b9aSArmin Le Grand             case( BMP_FORMAT_8BIT_PAL ):
101445fd3b9aSArmin Le Grand             case( BMP_FORMAT_24BIT_TC_BGR ):
101545fd3b9aSArmin Le Grand             {
101645fd3b9aSArmin Le Grand                 if(!pAccAlpha && rAcc.IsBottomUp() && (rAcc.GetScanlineSize() == nAlignedWidth))
101745fd3b9aSArmin Le Grand                 {
101845fd3b9aSArmin Le Grand                     bNative = true;
101945fd3b9aSArmin Le Grand                 }
102045fd3b9aSArmin Le Grand 
102145fd3b9aSArmin Le Grand                 break;
102245fd3b9aSArmin Le Grand             }
102345fd3b9aSArmin Le Grand 
102445fd3b9aSArmin Le Grand             default:
102545fd3b9aSArmin Le Grand             {
102645fd3b9aSArmin Le Grand                 break;
102745fd3b9aSArmin Le Grand             }
102845fd3b9aSArmin Le Grand         }
102945fd3b9aSArmin Le Grand 
103045fd3b9aSArmin Le Grand         rImageSize = rOStm.Tell();
103145fd3b9aSArmin Le Grand 
103245fd3b9aSArmin Le Grand         if(bNative)
103345fd3b9aSArmin Le Grand         {
103445fd3b9aSArmin Le Grand             rOStm.Write(rAcc.GetBuffer(), nAlignedWidth * rAcc.Height());
103545fd3b9aSArmin Le Grand         }
103645fd3b9aSArmin Le Grand         else
103745fd3b9aSArmin Le Grand         {
103845fd3b9aSArmin Le Grand             const long nWidth(rAcc.Width());
103945fd3b9aSArmin Le Grand             const long nHeight(rAcc.Height());
104045fd3b9aSArmin Le Grand             sal_uInt8* pBuf = new sal_uInt8[ nAlignedWidth ];
104145fd3b9aSArmin Le Grand             sal_uInt8* pTmp(0);
104245fd3b9aSArmin Le Grand             sal_uInt8 cTmp(0);
104345fd3b9aSArmin Le Grand 
104445fd3b9aSArmin Le Grand             switch( nBitCount )
104545fd3b9aSArmin Le Grand             {
104645fd3b9aSArmin Le Grand                 case( 1 ):
104745fd3b9aSArmin Le Grand                 {
104845fd3b9aSArmin Le Grand                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
104945fd3b9aSArmin Le Grand                     {
105045fd3b9aSArmin Le Grand                         pTmp = pBuf;
105145fd3b9aSArmin Le Grand                         cTmp = 0;
105245fd3b9aSArmin Le Grand 
105345fd3b9aSArmin Le Grand                         for( long nX = 0L, nShift = 8L; nX < nWidth; nX++ )
105445fd3b9aSArmin Le Grand                         {
105545fd3b9aSArmin Le Grand                             if( !nShift )
105645fd3b9aSArmin Le Grand                             {
105745fd3b9aSArmin Le Grand                                 nShift = 8L;
105845fd3b9aSArmin Le Grand                                 *pTmp++ = cTmp;
105945fd3b9aSArmin Le Grand                                 cTmp = 0;
106045fd3b9aSArmin Le Grand                             }
106145fd3b9aSArmin Le Grand 
106245fd3b9aSArmin Le Grand                             cTmp |= rAcc.GetPixelIndex( nY, nX ) << --nShift;
106345fd3b9aSArmin Le Grand                         }
106445fd3b9aSArmin Le Grand 
106545fd3b9aSArmin Le Grand                         *pTmp = cTmp;
106645fd3b9aSArmin Le Grand                         rOStm.Write( pBuf, nAlignedWidth );
106745fd3b9aSArmin Le Grand                     }
106845fd3b9aSArmin Le Grand                 }
106945fd3b9aSArmin Le Grand                 break;
107045fd3b9aSArmin Le Grand 
107145fd3b9aSArmin Le Grand                 case( 4 ):
107245fd3b9aSArmin Le Grand                 {
107345fd3b9aSArmin Le Grand                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
107445fd3b9aSArmin Le Grand                     {
107545fd3b9aSArmin Le Grand                         pTmp = pBuf;
107645fd3b9aSArmin Le Grand                         cTmp = 0;
107745fd3b9aSArmin Le Grand 
107845fd3b9aSArmin Le Grand                         for( long nX = 0L, nShift = 2L; nX < nWidth; nX++ )
107945fd3b9aSArmin Le Grand                         {
108045fd3b9aSArmin Le Grand                             if( !nShift )
108145fd3b9aSArmin Le Grand                             {
108245fd3b9aSArmin Le Grand                                 nShift = 2L;
108345fd3b9aSArmin Le Grand                                 *pTmp++ = cTmp;
108445fd3b9aSArmin Le Grand                                 cTmp = 0;
108545fd3b9aSArmin Le Grand                             }
108645fd3b9aSArmin Le Grand 
108745fd3b9aSArmin Le Grand                             cTmp |= rAcc.GetPixelIndex( nY, nX ) << ( --nShift << 2L );
108845fd3b9aSArmin Le Grand                         }
108945fd3b9aSArmin Le Grand                         *pTmp = cTmp;
109045fd3b9aSArmin Le Grand                         rOStm.Write( pBuf, nAlignedWidth );
109145fd3b9aSArmin Le Grand                     }
109245fd3b9aSArmin Le Grand                 }
109345fd3b9aSArmin Le Grand                 break;
109445fd3b9aSArmin Le Grand 
109545fd3b9aSArmin Le Grand                 case( 8 ):
109645fd3b9aSArmin Le Grand                 {
109745fd3b9aSArmin Le Grand                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
109845fd3b9aSArmin Le Grand                     {
109945fd3b9aSArmin Le Grand                         pTmp = pBuf;
110045fd3b9aSArmin Le Grand 
110145fd3b9aSArmin Le Grand                         for( long nX = 0L; nX < nWidth; nX++ )
110245fd3b9aSArmin Le Grand                             *pTmp++ = rAcc.GetPixelIndex( nY, nX );
110345fd3b9aSArmin Le Grand 
110445fd3b9aSArmin Le Grand                         rOStm.Write( pBuf, nAlignedWidth );
110545fd3b9aSArmin Le Grand                     }
110645fd3b9aSArmin Le Grand                 }
110745fd3b9aSArmin Le Grand                 break;
110845fd3b9aSArmin Le Grand 
110945fd3b9aSArmin Le Grand                 // #i59239# fallback to 24 bit format, if bitcount is non-default
111045fd3b9aSArmin Le Grand                 default:
111145fd3b9aSArmin Le Grand                     // FALLTHROUGH intended
111245fd3b9aSArmin Le Grand                 case( 24 ):
111345fd3b9aSArmin Le Grand                 {
111445fd3b9aSArmin Le Grand                     BitmapColor aPixelColor;
111545fd3b9aSArmin Le Grand                     const bool bWriteAlpha(32 == nBitCount && pAccAlpha);
111645fd3b9aSArmin Le Grand 
111745fd3b9aSArmin Le Grand                     for( long nY = nHeight - 1; nY >= 0L; nY-- )
111845fd3b9aSArmin Le Grand                     {
111945fd3b9aSArmin Le Grand                         pTmp = pBuf;
112045fd3b9aSArmin Le Grand 
112145fd3b9aSArmin Le Grand                         for( long nX = 0L; nX < nWidth; nX++ )
112245fd3b9aSArmin Le Grand                         {
112345fd3b9aSArmin Le Grand                             // when alpha is used, this may be non-24bit main bitmap, so use GetColor
112445fd3b9aSArmin Le Grand                             // instead of GetPixel to ensure RGB value
112545fd3b9aSArmin Le Grand                             aPixelColor = rAcc.GetColor( nY, nX );
112645fd3b9aSArmin Le Grand 
112745fd3b9aSArmin Le Grand                             *pTmp++ = aPixelColor.GetBlue();
112845fd3b9aSArmin Le Grand                             *pTmp++ = aPixelColor.GetGreen();
112945fd3b9aSArmin Le Grand                             *pTmp++ = aPixelColor.GetRed();
113045fd3b9aSArmin Le Grand 
113145fd3b9aSArmin Le Grand                             if(bWriteAlpha)
113245fd3b9aSArmin Le Grand                             {
113345fd3b9aSArmin Le Grand                                 if(pAccAlpha)
113445fd3b9aSArmin Le Grand                                 {
113545fd3b9aSArmin Le Grand                                     *pTmp++ = (sal_uInt8)0xff - (sal_uInt8)pAccAlpha->GetPixelIndex( nY, nX );
113645fd3b9aSArmin Le Grand                                 }
113745fd3b9aSArmin Le Grand                                 else
113845fd3b9aSArmin Le Grand                                 {
113945fd3b9aSArmin Le Grand                                     *pTmp++ = (sal_uInt8)0xff;
114045fd3b9aSArmin Le Grand                                 }
114145fd3b9aSArmin Le Grand                             }
114245fd3b9aSArmin Le Grand                         }
114345fd3b9aSArmin Le Grand 
114445fd3b9aSArmin Le Grand                         rOStm.Write( pBuf, nAlignedWidth );
114545fd3b9aSArmin Le Grand                     }
114645fd3b9aSArmin Le Grand                 }
114745fd3b9aSArmin Le Grand                 break;
114845fd3b9aSArmin Le Grand             }
114945fd3b9aSArmin Le Grand 
115045fd3b9aSArmin Le Grand             delete[] pBuf;
115145fd3b9aSArmin Le Grand         }
115245fd3b9aSArmin Le Grand     }
115345fd3b9aSArmin Le Grand 
115445fd3b9aSArmin Le Grand     rImageSize = rOStm.Tell() - rImageSize;
115545fd3b9aSArmin Le Grand 
115645fd3b9aSArmin Le Grand     return (!rOStm.GetError());
115745fd3b9aSArmin Le Grand }
115845fd3b9aSArmin Le Grand 
ImplWriteDIBBody(const Bitmap & rBitmap,SvStream & rOStm,BitmapReadAccess & rAcc,BitmapReadAccess * pAccAlpha,bool bCompressed)115945fd3b9aSArmin Le Grand bool ImplWriteDIBBody(const Bitmap& rBitmap, SvStream& rOStm, BitmapReadAccess& rAcc, BitmapReadAccess* pAccAlpha, bool bCompressed)
116045fd3b9aSArmin Le Grand {
116145fd3b9aSArmin Le Grand     const MapMode aMapPixel(MAP_PIXEL);
116245fd3b9aSArmin Le Grand     DIBV5Header aHeader;
116345fd3b9aSArmin Le Grand     sal_uLong nImageSizePos(0);
116445fd3b9aSArmin Le Grand     sal_uLong nEndPos(0);
116545fd3b9aSArmin Le Grand     sal_uInt32 nCompression(COMPRESS_NONE);
116645fd3b9aSArmin Le Grand     bool bRet(false);
116745fd3b9aSArmin Le Grand 
116845fd3b9aSArmin Le Grand     aHeader.nSize = pAccAlpha ? DIBV5HEADERSIZE : DIBINFOHEADERSIZE; // size dependent on CF_DIB type to use
116945fd3b9aSArmin Le Grand     aHeader.nWidth = rAcc.Width();
117045fd3b9aSArmin Le Grand     aHeader.nHeight = rAcc.Height();
117145fd3b9aSArmin Le Grand     aHeader.nPlanes = 1;
117245fd3b9aSArmin Le Grand 
117345fd3b9aSArmin Le Grand     if(!pAccAlpha && isBitfieldCompression(rAcc.GetScanlineFormat()))
117445fd3b9aSArmin Le Grand     {
117545fd3b9aSArmin Le Grand         aHeader.nBitCount = (BMP_FORMAT_16BIT_TC_LSB_MASK == rAcc.GetScanlineFormat()) ? 16 : 32;
117645fd3b9aSArmin Le Grand         aHeader.nSizeImage = rAcc.Height() * rAcc.GetScanlineSize();
117745fd3b9aSArmin Le Grand         nCompression = BITFIELDS;
117845fd3b9aSArmin Le Grand     }
117945fd3b9aSArmin Le Grand     else
118045fd3b9aSArmin Le Grand     {
118145fd3b9aSArmin Le Grand         // #i5xxx# Limit bitcount to 24bit, the 32 bit cases are
118245fd3b9aSArmin Le Grand         // not handled properly below (would have to set color
118345fd3b9aSArmin Le Grand         // masks, and nCompression=BITFIELDS - but color mask is
118445fd3b9aSArmin Le Grand         // not set for formats != *_TC_*). Note that this very
118545fd3b9aSArmin Le Grand         // problem might cause trouble at other places - the
118645fd3b9aSArmin Le Grand         // introduction of 32 bit RGBA bitmaps is relatively
118745fd3b9aSArmin Le Grand         // recent.
118845fd3b9aSArmin Le Grand         // #i59239# discretize bitcount to 1,4,8,24 (other cases
118945fd3b9aSArmin Le Grand         // are not written below)
119045fd3b9aSArmin Le Grand         const sal_uInt16 nBitCount(pAccAlpha ? 32 : discretizeBitcount(static_cast< sal_uInt16 >(rAcc.GetBitCount())));
119145fd3b9aSArmin Le Grand         aHeader.nBitCount = nBitCount;
119245fd3b9aSArmin Le Grand         aHeader.nSizeImage = rAcc.Height() * AlignedWidth4Bytes(rAcc.Width() * aHeader.nBitCount);
119345fd3b9aSArmin Le Grand 
119445fd3b9aSArmin Le Grand         if(bCompressed)
119545fd3b9aSArmin Le Grand         {
119645fd3b9aSArmin Le Grand             if(4 == nBitCount)
119745fd3b9aSArmin Le Grand             {
119845fd3b9aSArmin Le Grand                 nCompression = RLE_4;
119945fd3b9aSArmin Le Grand             }
120045fd3b9aSArmin Le Grand             else if(8 == nBitCount)
120145fd3b9aSArmin Le Grand             {
120245fd3b9aSArmin Le Grand                 nCompression = RLE_8;
120345fd3b9aSArmin Le Grand             }
120445fd3b9aSArmin Le Grand         }
120545fd3b9aSArmin Le Grand     }
120645fd3b9aSArmin Le Grand 
120745fd3b9aSArmin Le Grand     if((rOStm.GetCompressMode() & COMPRESSMODE_ZBITMAP) && (rOStm.GetVersion() >= SOFFICE_FILEFORMAT_40))
120845fd3b9aSArmin Le Grand     {
120945fd3b9aSArmin Le Grand         aHeader.nCompression = ZCOMPRESS;
121045fd3b9aSArmin Le Grand     }
121145fd3b9aSArmin Le Grand     else
121245fd3b9aSArmin Le Grand     {
121345fd3b9aSArmin Le Grand         aHeader.nCompression = nCompression;
121445fd3b9aSArmin Le Grand     }
121545fd3b9aSArmin Le Grand 
121645fd3b9aSArmin Le Grand     if(rBitmap.GetPrefSize().Width() && rBitmap.GetPrefSize().Height() && (rBitmap.GetPrefMapMode() != aMapPixel))
121745fd3b9aSArmin Le Grand     {
121845fd3b9aSArmin Le Grand         // #i48108# Try to recover xpels/ypels as previously stored on
121945fd3b9aSArmin Le Grand         // disk. The problem with just converting maPrefSize to 100th
122045fd3b9aSArmin Le Grand         // mm and then relating that to the bitmap pixel size is that
122145fd3b9aSArmin Le Grand         // MapMode is integer-based, and suffers from roundoffs,
122245fd3b9aSArmin Le Grand         // especially if maPrefSize is small. Trying to circumvent
122345fd3b9aSArmin Le Grand         // that by performing part of the math in floating point.
122445fd3b9aSArmin Le Grand         const Size aScale100000(OutputDevice::LogicToLogic(Size(100000L, 100000L), MAP_100TH_MM, rBitmap.GetPrefMapMode()));
122545fd3b9aSArmin Le Grand         const double fBmpWidthM((double)rBitmap.GetPrefSize().Width() / aScale100000.Width());
122645fd3b9aSArmin Le Grand         const double fBmpHeightM((double)rBitmap.GetPrefSize().Height() / aScale100000.Height());
122745fd3b9aSArmin Le Grand 
122845fd3b9aSArmin Le Grand         if(!basegfx::fTools::equalZero(fBmpWidthM) && !basegfx::fTools::equalZero(fBmpHeightM))
122945fd3b9aSArmin Le Grand         {
123045fd3b9aSArmin Le Grand             aHeader.nXPelsPerMeter = basegfx::fround(rAcc.Width() / fabs(fBmpWidthM));
123145fd3b9aSArmin Le Grand             aHeader.nYPelsPerMeter = basegfx::fround(rAcc.Height() / fabs(fBmpHeightM));
123245fd3b9aSArmin Le Grand         }
123345fd3b9aSArmin Le Grand     }
123445fd3b9aSArmin Le Grand 
123545fd3b9aSArmin Le Grand     aHeader.nColsUsed = ((!pAccAlpha && aHeader.nBitCount <= 8) ? rAcc.GetPaletteEntryCount() : 0);
123645fd3b9aSArmin Le Grand     aHeader.nColsImportant = 0;
123745fd3b9aSArmin Le Grand 
123845fd3b9aSArmin Le Grand     rOStm << aHeader.nSize;
123945fd3b9aSArmin Le Grand     rOStm << aHeader.nWidth;
124045fd3b9aSArmin Le Grand     rOStm << aHeader.nHeight;
124145fd3b9aSArmin Le Grand     rOStm << aHeader.nPlanes;
124245fd3b9aSArmin Le Grand     rOStm << aHeader.nBitCount;
124345fd3b9aSArmin Le Grand     rOStm << aHeader.nCompression;
124445fd3b9aSArmin Le Grand 
124545fd3b9aSArmin Le Grand     nImageSizePos = rOStm.Tell();
124645fd3b9aSArmin Le Grand     rOStm.SeekRel( sizeof( aHeader.nSizeImage ) );
124745fd3b9aSArmin Le Grand 
124845fd3b9aSArmin Le Grand     rOStm << aHeader.nXPelsPerMeter;
124945fd3b9aSArmin Le Grand     rOStm << aHeader.nYPelsPerMeter;
125045fd3b9aSArmin Le Grand     rOStm << aHeader.nColsUsed;
125145fd3b9aSArmin Le Grand     rOStm << aHeader.nColsImportant;
125245fd3b9aSArmin Le Grand 
125345fd3b9aSArmin Le Grand     if(pAccAlpha) // only write DIBV5 when asked to do so
125445fd3b9aSArmin Le Grand     {
125545fd3b9aSArmin Le Grand         aHeader.nV5CSType = 0x57696E20; // LCS_WINDOWS_COLOR_SPACE
1256c7a371deSArmin Le Grand         aHeader.nV5Intent = 0x00000004; // LCS_GM_IMAGES
125745fd3b9aSArmin Le Grand 
125845fd3b9aSArmin Le Grand         rOStm << aHeader.nV5RedMask;
125945fd3b9aSArmin Le Grand         rOStm << aHeader.nV5GreenMask;
126045fd3b9aSArmin Le Grand         rOStm << aHeader.nV5BlueMask;
126145fd3b9aSArmin Le Grand         rOStm << aHeader.nV5AlphaMask;
126245fd3b9aSArmin Le Grand         rOStm << aHeader.nV5CSType;
126345fd3b9aSArmin Le Grand 
126445fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzRed.aXyzX;
126545fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzRed.aXyzY;
126645fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzRed.aXyzZ;
126745fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzGreen.aXyzX;
126845fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzGreen.aXyzY;
126945fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzGreen.aXyzZ;
127045fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzBlue.aXyzX;
127145fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzBlue.aXyzY;
127245fd3b9aSArmin Le Grand         rOStm << aHeader.aV5Endpoints.aXyzBlue.aXyzZ;
127345fd3b9aSArmin Le Grand 
127445fd3b9aSArmin Le Grand         rOStm << aHeader.nV5GammaRed;
127545fd3b9aSArmin Le Grand         rOStm << aHeader.nV5GammaGreen;
127645fd3b9aSArmin Le Grand         rOStm << aHeader.nV5GammaBlue;
127745fd3b9aSArmin Le Grand         rOStm << aHeader.nV5Intent;
127845fd3b9aSArmin Le Grand         rOStm << aHeader.nV5ProfileData;
127945fd3b9aSArmin Le Grand         rOStm << aHeader.nV5ProfileSize;
128045fd3b9aSArmin Le Grand         rOStm << aHeader.nV5Reserved;
128145fd3b9aSArmin Le Grand     }
128245fd3b9aSArmin Le Grand 
128345fd3b9aSArmin Le Grand     if(ZCOMPRESS == aHeader.nCompression)
128445fd3b9aSArmin Le Grand     {
128545fd3b9aSArmin Le Grand         ZCodec aCodec;
128645fd3b9aSArmin Le Grand         SvMemoryStream aMemStm(aHeader.nSizeImage + 4096, 65535);
128745fd3b9aSArmin Le Grand         sal_uLong nCodedPos(rOStm.Tell());
128845fd3b9aSArmin Le Grand         sal_uLong nLastPos(0);
128945fd3b9aSArmin Le Grand         sal_uInt32 nCodedSize(0);
129045fd3b9aSArmin Le Grand         sal_uInt32 nUncodedSize(0);
129145fd3b9aSArmin Le Grand 
129245fd3b9aSArmin Le Grand         // write uncoded data palette
129345fd3b9aSArmin Le Grand         if(aHeader.nColsUsed)
129445fd3b9aSArmin Le Grand         {
129545fd3b9aSArmin Le Grand             ImplWriteDIBPalette(aMemStm, rAcc);
129645fd3b9aSArmin Le Grand         }
129745fd3b9aSArmin Le Grand 
129845fd3b9aSArmin Le Grand         // write uncoded bits
129945fd3b9aSArmin Le Grand         bRet = ImplWriteDIBBits(aMemStm, rAcc, pAccAlpha, nCompression, aHeader.nSizeImage);
130045fd3b9aSArmin Le Grand 
130145fd3b9aSArmin Le Grand         // get uncoded size
130245fd3b9aSArmin Le Grand         nUncodedSize = aMemStm.Tell();
130345fd3b9aSArmin Le Grand 
130445fd3b9aSArmin Le Grand         // seek over compress info
130545fd3b9aSArmin Le Grand         rOStm.SeekRel(12);
130645fd3b9aSArmin Le Grand 
130745fd3b9aSArmin Le Grand         // write compressed data
130845fd3b9aSArmin Le Grand         aCodec.BeginCompression(3);
130945fd3b9aSArmin Le Grand         aCodec.Write(rOStm, (sal_uInt8*)aMemStm.GetData(), nUncodedSize);
131045fd3b9aSArmin Le Grand         aCodec.EndCompression();
131145fd3b9aSArmin Le Grand 
131245fd3b9aSArmin Le Grand         // update compress info ( coded size, uncoded size, uncoded compression )
131345fd3b9aSArmin Le Grand         nLastPos = rOStm.Tell();
131445fd3b9aSArmin Le Grand         nCodedSize = nLastPos - nCodedPos - 12;
131545fd3b9aSArmin Le Grand         rOStm.Seek(nCodedPos);
131645fd3b9aSArmin Le Grand         rOStm << nCodedSize << nUncodedSize << nCompression;
131745fd3b9aSArmin Le Grand         rOStm.Seek(nLastPos);
131845fd3b9aSArmin Le Grand 
131945fd3b9aSArmin Le Grand         if(bRet)
132045fd3b9aSArmin Le Grand         {
132145fd3b9aSArmin Le Grand             bRet = (ERRCODE_NONE == rOStm.GetError());
132245fd3b9aSArmin Le Grand         }
132345fd3b9aSArmin Le Grand     }
132445fd3b9aSArmin Le Grand     else
132545fd3b9aSArmin Le Grand     {
132645fd3b9aSArmin Le Grand         if(aHeader.nColsUsed)
132745fd3b9aSArmin Le Grand         {
132845fd3b9aSArmin Le Grand             ImplWriteDIBPalette(rOStm, rAcc);
132945fd3b9aSArmin Le Grand         }
133045fd3b9aSArmin Le Grand 
133145fd3b9aSArmin Le Grand         bRet = ImplWriteDIBBits(rOStm, rAcc, pAccAlpha, aHeader.nCompression, aHeader.nSizeImage);
133245fd3b9aSArmin Le Grand     }
133345fd3b9aSArmin Le Grand 
133445fd3b9aSArmin Le Grand     nEndPos = rOStm.Tell();
133545fd3b9aSArmin Le Grand     rOStm.Seek(nImageSizePos);
133645fd3b9aSArmin Le Grand     rOStm << aHeader.nSizeImage;
133745fd3b9aSArmin Le Grand     rOStm.Seek(nEndPos);
133845fd3b9aSArmin Le Grand 
133945fd3b9aSArmin Le Grand     return bRet;
134045fd3b9aSArmin Le Grand }
134145fd3b9aSArmin Le Grand 
ImplWriteDIBFileHeader(SvStream & rOStm,BitmapReadAccess & rAcc,bool bUseDIBV5)134245fd3b9aSArmin Le Grand bool ImplWriteDIBFileHeader(SvStream& rOStm, BitmapReadAccess& rAcc, bool bUseDIBV5)
134345fd3b9aSArmin Le Grand {
134445fd3b9aSArmin Le Grand     const sal_uInt32 nPalCount((rAcc.HasPalette() ? rAcc.GetPaletteEntryCount() : isBitfieldCompression(rAcc.GetScanlineFormat()) ? 3UL : 0UL));
134545fd3b9aSArmin Le Grand     const sal_uInt32 nOffset(14 + (bUseDIBV5 ? DIBV5HEADERSIZE : DIBINFOHEADERSIZE) + nPalCount * 4UL);
134645fd3b9aSArmin Le Grand 
134745fd3b9aSArmin Le Grand     rOStm << (sal_uInt16)0x4D42; // 'MB' from BITMAPFILEHEADER
134845fd3b9aSArmin Le Grand     rOStm << (sal_uInt32)(nOffset + (rAcc.Height() * rAcc.GetScanlineSize()));
134945fd3b9aSArmin Le Grand     rOStm << (sal_uInt16)0;
135045fd3b9aSArmin Le Grand     rOStm << (sal_uInt16)0;
135145fd3b9aSArmin Le Grand     rOStm << nOffset;
135245fd3b9aSArmin Le Grand 
135345fd3b9aSArmin Le Grand     return( rOStm.GetError() == 0UL );
135445fd3b9aSArmin Le Grand }
135545fd3b9aSArmin Le Grand 
135645fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
135745fd3b9aSArmin Le Grand 
ImplReadDIB(Bitmap & rTarget,Bitmap * pTargetAlpha,SvStream & rIStm,bool bFileHeader)135845fd3b9aSArmin Le Grand bool ImplReadDIB(
135945fd3b9aSArmin Le Grand     Bitmap& rTarget, Bitmap*
136045fd3b9aSArmin Le Grand     pTargetAlpha,
136145fd3b9aSArmin Le Grand     SvStream& rIStm,
136245fd3b9aSArmin Le Grand     bool bFileHeader)
136345fd3b9aSArmin Le Grand {
136445fd3b9aSArmin Le Grand     const sal_uInt16 nOldFormat(rIStm.GetNumberFormatInt());
136545fd3b9aSArmin Le Grand     const sal_uLong nOldPos(rIStm.Tell());
136645fd3b9aSArmin Le Grand     sal_uLong nOffset(0UL);
136745fd3b9aSArmin Le Grand     bool bRet(false);
136845fd3b9aSArmin Le Grand 
136945fd3b9aSArmin Le Grand     rIStm.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
137045fd3b9aSArmin Le Grand 
137145fd3b9aSArmin Le Grand     if(bFileHeader)
137245fd3b9aSArmin Le Grand     {
137345fd3b9aSArmin Le Grand         if(ImplReadDIBFileHeader(rIStm, nOffset))
137445fd3b9aSArmin Le Grand         {
137545fd3b9aSArmin Le Grand             bRet = ImplReadDIBBody(rIStm, rTarget, nOffset >= DIBV5HEADERSIZE ? pTargetAlpha : 0, nOffset);
137645fd3b9aSArmin Le Grand         }
137745fd3b9aSArmin Le Grand     }
137845fd3b9aSArmin Le Grand     else
137945fd3b9aSArmin Le Grand     {
138045fd3b9aSArmin Le Grand         bRet = ImplReadDIBBody(rIStm, rTarget, 0, nOffset);
138145fd3b9aSArmin Le Grand     }
138245fd3b9aSArmin Le Grand 
138345fd3b9aSArmin Le Grand     if(!bRet)
138445fd3b9aSArmin Le Grand     {
138545fd3b9aSArmin Le Grand         if(!rIStm.GetError())
138645fd3b9aSArmin Le Grand         {
138745fd3b9aSArmin Le Grand             rIStm.SetError(SVSTREAM_GENERALERROR);
138845fd3b9aSArmin Le Grand         }
138945fd3b9aSArmin Le Grand 
139045fd3b9aSArmin Le Grand         rIStm.Seek(nOldPos);
139145fd3b9aSArmin Le Grand     }
139245fd3b9aSArmin Le Grand 
139345fd3b9aSArmin Le Grand     rIStm.SetNumberFormatInt(nOldFormat);
139445fd3b9aSArmin Le Grand 
139545fd3b9aSArmin Le Grand     return bRet;
139645fd3b9aSArmin Le Grand }
139745fd3b9aSArmin Le Grand 
ImplWriteDIB(const Bitmap & rSource,const Bitmap * pSourceAlpha,SvStream & rOStm,bool bCompressed,bool bFileHeader)139845fd3b9aSArmin Le Grand bool ImplWriteDIB(
139945fd3b9aSArmin Le Grand     const Bitmap& rSource,
140045fd3b9aSArmin Le Grand     const Bitmap* pSourceAlpha,
140145fd3b9aSArmin Le Grand     SvStream& rOStm,
140245fd3b9aSArmin Le Grand     bool bCompressed,
140345fd3b9aSArmin Le Grand     bool bFileHeader)
140445fd3b9aSArmin Le Grand {
140545fd3b9aSArmin Le Grand     const Size aSizePix(rSource.GetSizePixel());
140645fd3b9aSArmin Le Grand     bool bRet(false);
140745fd3b9aSArmin Le Grand 
140845fd3b9aSArmin Le Grand     if(aSizePix.Width() && aSizePix.Height())
140945fd3b9aSArmin Le Grand     {
141045fd3b9aSArmin Le Grand         BitmapReadAccess* pAcc = const_cast< Bitmap& >(rSource).AcquireReadAccess();
141145fd3b9aSArmin Le Grand         BitmapReadAccess* pAccAlpha = 0;
141245fd3b9aSArmin Le Grand         const sal_uInt16 nOldFormat(rOStm.GetNumberFormatInt());
141345fd3b9aSArmin Le Grand         const sal_uLong nOldPos(rOStm.Tell());
141445fd3b9aSArmin Le Grand 
141545fd3b9aSArmin Le Grand         if(pSourceAlpha)
141645fd3b9aSArmin Le Grand         {
141745fd3b9aSArmin Le Grand             const Size aSizePixAlpha(pSourceAlpha->GetSizePixel());
141845fd3b9aSArmin Le Grand 
141945fd3b9aSArmin Le Grand             if(aSizePixAlpha == aSizePix)
142045fd3b9aSArmin Le Grand             {
142145fd3b9aSArmin Le Grand                 pAccAlpha = const_cast< Bitmap* >(pSourceAlpha)->AcquireReadAccess();
142245fd3b9aSArmin Le Grand             }
142345fd3b9aSArmin Le Grand             else
142445fd3b9aSArmin Le Grand             {
142545fd3b9aSArmin Le Grand                 OSL_ENSURE(false, "WriteDIB got an alpha channel, but it's pixel size differs from the base bitmap (!)");
142645fd3b9aSArmin Le Grand             }
142745fd3b9aSArmin Le Grand         }
142845fd3b9aSArmin Le Grand 
142945fd3b9aSArmin Le Grand         rOStm.SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
143045fd3b9aSArmin Le Grand 
143145fd3b9aSArmin Le Grand         if(pAcc)
143245fd3b9aSArmin Le Grand         {
143345fd3b9aSArmin Le Grand             if(bFileHeader)
143445fd3b9aSArmin Le Grand             {
143545fd3b9aSArmin Le Grand                 if(ImplWriteDIBFileHeader(rOStm, *pAcc, 0 != pSourceAlpha))
143645fd3b9aSArmin Le Grand                 {
143745fd3b9aSArmin Le Grand                     bRet = ImplWriteDIBBody(rSource, rOStm, *pAcc, pAccAlpha, bCompressed);
143845fd3b9aSArmin Le Grand                 }
143945fd3b9aSArmin Le Grand             }
144045fd3b9aSArmin Le Grand             else
144145fd3b9aSArmin Le Grand             {
144245fd3b9aSArmin Le Grand                 bRet = ImplWriteDIBBody(rSource, rOStm, *pAcc, pAccAlpha, bCompressed);
144345fd3b9aSArmin Le Grand             }
144445fd3b9aSArmin Le Grand 
144545fd3b9aSArmin Le Grand             const_cast< Bitmap& >(rSource).ReleaseAccess(pAcc);
144645fd3b9aSArmin Le Grand 
144745fd3b9aSArmin Le Grand             if(pAccAlpha)
144845fd3b9aSArmin Le Grand             {
144945fd3b9aSArmin Le Grand                 const_cast< Bitmap* >(pSourceAlpha)->ReleaseAccess(pAccAlpha);
145045fd3b9aSArmin Le Grand             }
145145fd3b9aSArmin Le Grand         }
145245fd3b9aSArmin Le Grand 
145345fd3b9aSArmin Le Grand         if(!bRet)
145445fd3b9aSArmin Le Grand         {
145545fd3b9aSArmin Le Grand             rOStm.SetError(SVSTREAM_GENERALERROR);
145645fd3b9aSArmin Le Grand             rOStm.Seek(nOldPos);
145745fd3b9aSArmin Le Grand         }
145845fd3b9aSArmin Le Grand 
145945fd3b9aSArmin Le Grand         rOStm.SetNumberFormatInt(nOldFormat);
146045fd3b9aSArmin Le Grand     }
146145fd3b9aSArmin Le Grand 
146245fd3b9aSArmin Le Grand     return bRet;
146345fd3b9aSArmin Le Grand }
146445fd3b9aSArmin Le Grand 
146545fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
146645fd3b9aSArmin Le Grand 
ReadDIB(Bitmap & rTarget,SvStream & rIStm,bool bFileHeader)146745fd3b9aSArmin Le Grand bool ReadDIB(
146845fd3b9aSArmin Le Grand     Bitmap& rTarget,
146945fd3b9aSArmin Le Grand     SvStream& rIStm,
147045fd3b9aSArmin Le Grand     bool bFileHeader)
147145fd3b9aSArmin Le Grand {
147245fd3b9aSArmin Le Grand     return ImplReadDIB(rTarget, 0, rIStm, bFileHeader);
147345fd3b9aSArmin Le Grand }
147445fd3b9aSArmin Le Grand 
ReadDIBBitmapEx(BitmapEx & rTarget,SvStream & rIStm)147545fd3b9aSArmin Le Grand bool ReadDIBBitmapEx(
147645fd3b9aSArmin Le Grand     BitmapEx& rTarget,
147745fd3b9aSArmin Le Grand     SvStream& rIStm)
147845fd3b9aSArmin Le Grand {
147945fd3b9aSArmin Le Grand     Bitmap aBmp;
148045fd3b9aSArmin Le Grand     bool bRetval(ImplReadDIB(aBmp, 0, rIStm, true) && !rIStm.GetError());
148145fd3b9aSArmin Le Grand 
148245fd3b9aSArmin Le Grand     if(bRetval)
148345fd3b9aSArmin Le Grand     {
148445fd3b9aSArmin Le Grand         // base bitmap was read, set as return value and try to read alpha extra-data
148545fd3b9aSArmin Le Grand         const sal_uLong nStmPos(rIStm.Tell());
148645fd3b9aSArmin Le Grand         sal_uInt32 nMagic1(0);
148745fd3b9aSArmin Le Grand         sal_uInt32 nMagic2(0);
148845fd3b9aSArmin Le Grand 
148945fd3b9aSArmin Le Grand         rTarget = BitmapEx(aBmp);
149045fd3b9aSArmin Le Grand         rIStm >> nMagic1 >> nMagic2;
149145fd3b9aSArmin Le Grand         bRetval = (0x25091962 == nMagic1) && (0xACB20201 == nMagic2) && !rIStm.GetError();
149245fd3b9aSArmin Le Grand 
149345fd3b9aSArmin Le Grand         if(bRetval)
149445fd3b9aSArmin Le Grand         {
149545fd3b9aSArmin Le Grand             sal_uInt8 bTransparent(false);
149645fd3b9aSArmin Le Grand 
149745fd3b9aSArmin Le Grand             rIStm >> bTransparent;
149845fd3b9aSArmin Le Grand             bRetval = !rIStm.GetError();
149945fd3b9aSArmin Le Grand 
150045fd3b9aSArmin Le Grand             if(bRetval)
150145fd3b9aSArmin Le Grand             {
150245fd3b9aSArmin Le Grand                 if((sal_uInt8)TRANSPARENT_BITMAP == bTransparent)
150345fd3b9aSArmin Le Grand                 {
150445fd3b9aSArmin Le Grand                     Bitmap aMask;
150545fd3b9aSArmin Le Grand 
150645fd3b9aSArmin Le Grand                     bRetval = ImplReadDIB(aMask, 0, rIStm, true);
150745fd3b9aSArmin Le Grand 
150845fd3b9aSArmin Le Grand                     if(bRetval)
150945fd3b9aSArmin Le Grand                     {
151045fd3b9aSArmin Le Grand                         if(!!aMask)
151145fd3b9aSArmin Le Grand                         {
151245fd3b9aSArmin Le Grand                             // do we have an alpha mask?
151345fd3b9aSArmin Le Grand                             if((8 == aMask.GetBitCount()) && aMask.HasGreyPalette())
151445fd3b9aSArmin Le Grand                             {
151545fd3b9aSArmin Le Grand                                 AlphaMask aAlpha;
151645fd3b9aSArmin Le Grand 
151745fd3b9aSArmin Le Grand                                 // create alpha mask quickly (without greyscale conversion)
151845fd3b9aSArmin Le Grand                                 aAlpha.ImplSetBitmap(aMask);
151945fd3b9aSArmin Le Grand                                 rTarget = BitmapEx(aBmp, aAlpha);
152045fd3b9aSArmin Le Grand                             }
152145fd3b9aSArmin Le Grand                             else
152245fd3b9aSArmin Le Grand                             {
152345fd3b9aSArmin Le Grand                                 rTarget = BitmapEx(aBmp, aMask);
152445fd3b9aSArmin Le Grand                             }
152545fd3b9aSArmin Le Grand                         }
152645fd3b9aSArmin Le Grand                     }
152745fd3b9aSArmin Le Grand                 }
152845fd3b9aSArmin Le Grand                 else if((sal_uInt8)TRANSPARENT_COLOR == bTransparent)
152945fd3b9aSArmin Le Grand                 {
153045fd3b9aSArmin Le Grand                     Color aTransparentColor;
153145fd3b9aSArmin Le Grand 
153245fd3b9aSArmin Le Grand                     rIStm >> aTransparentColor;
153345fd3b9aSArmin Le Grand                     bRetval = !rIStm.GetError();
153445fd3b9aSArmin Le Grand 
153545fd3b9aSArmin Le Grand                     if(bRetval)
153645fd3b9aSArmin Le Grand                     {
153745fd3b9aSArmin Le Grand                         rTarget = BitmapEx(aBmp, aTransparentColor);
153845fd3b9aSArmin Le Grand                     }
153945fd3b9aSArmin Le Grand                 }
154045fd3b9aSArmin Le Grand             }
154145fd3b9aSArmin Le Grand         }
154245fd3b9aSArmin Le Grand 
154345fd3b9aSArmin Le Grand         if(!bRetval)
154445fd3b9aSArmin Le Grand         {
154545fd3b9aSArmin Le Grand             // alpha extra data could not be read; reset, but use base bitmap as result
154645fd3b9aSArmin Le Grand             rIStm.ResetError();
154745fd3b9aSArmin Le Grand             rIStm.Seek(nStmPos);
154845fd3b9aSArmin Le Grand             bRetval = true;
154945fd3b9aSArmin Le Grand         }
155045fd3b9aSArmin Le Grand     }
155145fd3b9aSArmin Le Grand 
155245fd3b9aSArmin Le Grand     return bRetval;
155345fd3b9aSArmin Le Grand }
155445fd3b9aSArmin Le Grand 
ReadDIBV5(Bitmap & rTarget,Bitmap & rTargetAlpha,SvStream & rIStm)155545fd3b9aSArmin Le Grand bool ReadDIBV5(
155645fd3b9aSArmin Le Grand     Bitmap& rTarget,
155745fd3b9aSArmin Le Grand     Bitmap& rTargetAlpha,
155845fd3b9aSArmin Le Grand     SvStream& rIStm)
155945fd3b9aSArmin Le Grand {
156045fd3b9aSArmin Le Grand     return ImplReadDIB(rTarget, &rTargetAlpha, rIStm, true);
156145fd3b9aSArmin Le Grand }
156245fd3b9aSArmin Le Grand 
156345fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
156445fd3b9aSArmin Le Grand 
WriteDIB(const Bitmap & rSource,SvStream & rOStm,bool bCompressed,bool bFileHeader)156545fd3b9aSArmin Le Grand bool WriteDIB(
156645fd3b9aSArmin Le Grand     const Bitmap& rSource,
156745fd3b9aSArmin Le Grand     SvStream& rOStm,
156845fd3b9aSArmin Le Grand     bool bCompressed,
156945fd3b9aSArmin Le Grand     bool bFileHeader)
157045fd3b9aSArmin Le Grand {
157145fd3b9aSArmin Le Grand     return ImplWriteDIB(rSource, 0, rOStm, bCompressed, bFileHeader);
157245fd3b9aSArmin Le Grand }
157345fd3b9aSArmin Le Grand 
WriteDIBBitmapEx(const BitmapEx & rSource,SvStream & rOStm)157445fd3b9aSArmin Le Grand bool WriteDIBBitmapEx(
157545fd3b9aSArmin Le Grand     const BitmapEx& rSource,
157645fd3b9aSArmin Le Grand     SvStream& rOStm)
157745fd3b9aSArmin Le Grand {
157845fd3b9aSArmin Le Grand     if(ImplWriteDIB(rSource.GetBitmap(), 0, rOStm, true, true))
157945fd3b9aSArmin Le Grand     {
158045fd3b9aSArmin Le Grand         rOStm << (sal_uInt32)0x25091962;
158145fd3b9aSArmin Le Grand         rOStm << (sal_uInt32)0xACB20201;
158245fd3b9aSArmin Le Grand         rOStm << (sal_uInt8)rSource.eTransparent;
158345fd3b9aSArmin Le Grand 
158445fd3b9aSArmin Le Grand         if(TRANSPARENT_BITMAP == rSource.eTransparent)
158545fd3b9aSArmin Le Grand         {
158645fd3b9aSArmin Le Grand             return ImplWriteDIB(rSource.aMask, 0, rOStm, true, true);
158745fd3b9aSArmin Le Grand         }
158845fd3b9aSArmin Le Grand         else if(TRANSPARENT_COLOR == rSource.eTransparent)
158945fd3b9aSArmin Le Grand         {
159045fd3b9aSArmin Le Grand             rOStm << rSource.aTransparentColor;
159145fd3b9aSArmin Le Grand             return true;
159245fd3b9aSArmin Le Grand         }
159345fd3b9aSArmin Le Grand     }
159445fd3b9aSArmin Le Grand 
159545fd3b9aSArmin Le Grand     return false;
159645fd3b9aSArmin Le Grand }
159745fd3b9aSArmin Le Grand 
WriteDIBV5(const Bitmap & rSource,const Bitmap & rSourceAlpha,SvStream & rOStm)159845fd3b9aSArmin Le Grand bool WriteDIBV5(
159945fd3b9aSArmin Le Grand     const Bitmap& rSource,
160045fd3b9aSArmin Le Grand     const Bitmap& rSourceAlpha,
160145fd3b9aSArmin Le Grand     SvStream& rOStm)
160245fd3b9aSArmin Le Grand {
160345fd3b9aSArmin Le Grand     return ImplWriteDIB(rSource, &rSourceAlpha, rOStm, false, true);
160445fd3b9aSArmin Le Grand }
160545fd3b9aSArmin Le Grand 
160645fd3b9aSArmin Le Grand //////////////////////////////////////////////////////////////////////////////
160745fd3b9aSArmin Le Grand // eof
1608