xref: /aoo41x/main/vcl/source/gdi/dibtools.cxx (revision 4b444595)
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 {
3933aedac3eSJürgen Schmidt     const sal_Int64 nBitsPerLine (static_cast<sal_Int64>(rHeader.nWidth) * static_cast<sal_Int64>(rHeader.nBitCount));
3943aedac3eSJürgen Schmidt     if (nBitsPerLine > SAL_MAX_UINT32)
3953aedac3eSJürgen Schmidt         return false;
3963aedac3eSJürgen Schmidt 
3973aedac3eSJü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)
432c7a371deSArmin Le Grand         {
433c7a371deSArmin Le Grand             rIStm.SeekRel( -12L );
434c7a371deSArmin Le Grand             rIStm >> nRMask;
435c7a371deSArmin Le Grand             rIStm >> nGMask;
436c7a371deSArmin Le Grand             rIStm >> nBMask;
437c7a371deSArmin 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 {
616*4b444595SOliver-Rainer Wittmann     DIBV5Header aHeader;
617*4b444595SOliver-Rainer Wittmann     const sal_uLong nStmPos = rIStm.Tell();
618*4b444595SOliver-Rainer Wittmann     bool bRet( false );
619*4b444595SOliver-Rainer Wittmann     bool bTopDown( false );
620*4b444595SOliver-Rainer Wittmann 
621*4b444595SOliver-Rainer Wittmann     if ( ImplReadDIBInfoHeader( rIStm, aHeader, bTopDown )
622*4b444595SOliver-Rainer Wittmann          && aHeader.nWidth != 0
623*4b444595SOliver-Rainer Wittmann          && aHeader.nHeight != 0
624*4b444595SOliver-Rainer Wittmann          && aHeader.nBitCount != 0 )
625*4b444595SOliver-Rainer Wittmann     {
626*4b444595SOliver-Rainer Wittmann         if ( nOffset > 0 && aHeader.nSize > nOffset )
6273aedac3eSJürgen Schmidt         {
6283aedac3eSJürgen Schmidt             // Header size claims to extend into the image data.
6293aedac3eSJürgen Schmidt             // Looks like an error.
6303aedac3eSJürgen Schmidt             return false;
6313aedac3eSJürgen Schmidt         }
6323aedac3eSJü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 {
7814e95292aSOliver-Rainer Wittmann     bool bRet = false;
78245fd3b9aSArmin Le Grand 
7834e95292aSOliver-Rainer Wittmann     const sal_Int64 nSavedStreamPos( rIStm.Tell() );
7844e95292aSOliver-Rainer Wittmann     const sal_Int64 nStreamLength( rIStm.Seek( STREAM_SEEK_TO_END ) );
7854e95292aSOliver-Rainer Wittmann     rIStm.Seek( nSavedStreamPos );
7863aedac3eSJürgen Schmidt 
7874e95292aSOliver-Rainer Wittmann     sal_uInt16 nTmp16 = 0;
7884e95292aSOliver-Rainer Wittmann     rIStm >> nTmp16;
78945fd3b9aSArmin Le Grand 
7904e95292aSOliver-Rainer Wittmann     if ( ( 0x4D42 == nTmp16 ) || ( 0x4142 == nTmp16 ) )
7914e95292aSOliver-Rainer Wittmann     {
7924e95292aSOliver-Rainer Wittmann         sal_uInt32 nTmp32;
7934e95292aSOliver-Rainer Wittmann         if ( 0x4142 == nTmp16 )
7944e95292aSOliver-Rainer Wittmann         {
7954e95292aSOliver-Rainer Wittmann             rIStm.SeekRel( 12L );
7964e95292aSOliver-Rainer Wittmann             rIStm >> nTmp16;
7974e95292aSOliver-Rainer Wittmann             rIStm.SeekRel( 8L );
7984e95292aSOliver-Rainer Wittmann             rIStm >> nTmp32;
7994e95292aSOliver-Rainer Wittmann             rOffset = nTmp32 - 28UL;
8004e95292aSOliver-Rainer Wittmann             bRet = ( 0x4D42 == nTmp16 );
8014e95292aSOliver-Rainer Wittmann         }
8024e95292aSOliver-Rainer Wittmann         else // 0x4D42 == nTmp16, 'MB' from BITMAPFILEHEADER
8034e95292aSOliver-Rainer Wittmann         {
8044e95292aSOliver-Rainer Wittmann             rIStm.SeekRel( 8L );        // we are on bfSize member of BITMAPFILEHEADER, forward to bfOffBits
8054e95292aSOliver-Rainer Wittmann             rIStm >> nTmp32;            // read bfOffBits
8064e95292aSOliver-Rainer Wittmann             rOffset = nTmp32 - 14UL;    // adapt offset by sizeof(BITMAPFILEHEADER)
8074e95292aSOliver-Rainer Wittmann             bRet = ( rIStm.GetError() == 0UL );
8084e95292aSOliver-Rainer Wittmann         }
8093aedac3eSJürgen Schmidt 
8104e95292aSOliver-Rainer Wittmann         if ( rOffset >= nStreamLength )
8113aedac3eSJürgen Schmidt         {
8123aedac3eSJürgen Schmidt             // Offset claims that image starts past the end of the
8133aedac3eSJürgen Schmidt             // stream.  Unlikely.
8143aedac3eSJürgen Schmidt             rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
8153aedac3eSJürgen Schmidt             bRet = false;
8163aedac3eSJürgen Schmidt         }
8174e95292aSOliver-Rainer Wittmann     }
8184e95292aSOliver-Rainer Wittmann     else
8194e95292aSOliver-Rainer Wittmann         rIStm.SetError( SVSTREAM_FILEFORMAT_ERROR );
82045fd3b9aSArmin Le Grand 
8214e95292aSOliver-Rainer Wittmann     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