xref: /aoo41x/main/vcl/win/source/gdi/salbmp.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_vcl.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <tools/svwin.h>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <vcl/bitmap.hxx> // for BitmapSystemData
34*cdf0e10cSrcweir #include <vcl/salbtype.hxx>
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <win/wincomp.hxx>
37*cdf0e10cSrcweir #include <win/salgdi.h>
38*cdf0e10cSrcweir #include <win/saldata.hxx>
39*cdf0e10cSrcweir #include <win/salbmp.h>
40*cdf0e10cSrcweir 
41*cdf0e10cSrcweir #include <string.h>
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir // -----------
44*cdf0e10cSrcweir // - Inlines -
45*cdf0e10cSrcweir // -----------
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex )
48*cdf0e10cSrcweir {
49*cdf0e10cSrcweir 	BYTE& rByte = pScanline[ nX >> 1 ];
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir 	( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) :
52*cdf0e10cSrcweir 				 ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) );
53*cdf0e10cSrcweir }
54*cdf0e10cSrcweir 
55*cdf0e10cSrcweir // ----------------
56*cdf0e10cSrcweir // - WinSalBitmap -
57*cdf0e10cSrcweir // ----------------
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir WinSalBitmap::WinSalBitmap() :
60*cdf0e10cSrcweir 		mhDIB		( 0 ),
61*cdf0e10cSrcweir 		mhDDB		( 0 ),
62*cdf0e10cSrcweir 		mnBitCount	( 0 )
63*cdf0e10cSrcweir {
64*cdf0e10cSrcweir }
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir // ------------------------------------------------------------------
67*cdf0e10cSrcweir 
68*cdf0e10cSrcweir WinSalBitmap::~WinSalBitmap()
69*cdf0e10cSrcweir {
70*cdf0e10cSrcweir 	Destroy();
71*cdf0e10cSrcweir }
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir // ------------------------------------------------------------------
74*cdf0e10cSrcweir 
75*cdf0e10cSrcweir bool WinSalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle )
76*cdf0e10cSrcweir {
77*cdf0e10cSrcweir 	bool bRet = TRUE;
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir 	if( bDIB )
80*cdf0e10cSrcweir 		mhDIB = (HGLOBAL) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap );
81*cdf0e10cSrcweir 	else
82*cdf0e10cSrcweir 		mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap );
83*cdf0e10cSrcweir 
84*cdf0e10cSrcweir 	if( mhDIB )
85*cdf0e10cSrcweir 	{
86*cdf0e10cSrcweir 		PBITMAPINFOHEADER pBIH = (PBITMAPINFOHEADER) GlobalLock( mhDIB );
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir 		maSize = Size( pBIH->biWidth, pBIH->biHeight );
89*cdf0e10cSrcweir 		mnBitCount = pBIH->biBitCount;
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir 		if( mnBitCount )
92*cdf0e10cSrcweir 			mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24;
93*cdf0e10cSrcweir 
94*cdf0e10cSrcweir 		GlobalUnlock( mhDIB );
95*cdf0e10cSrcweir 	}
96*cdf0e10cSrcweir 	else if( mhDDB )
97*cdf0e10cSrcweir 	{
98*cdf0e10cSrcweir 		BITMAP	aDDBInfo;
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir 		if( WIN_GetObject( mhDDB, sizeof( BITMAP ), &aDDBInfo ) )
101*cdf0e10cSrcweir 		{
102*cdf0e10cSrcweir 			maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
103*cdf0e10cSrcweir 			mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 			if( mnBitCount )
106*cdf0e10cSrcweir 			{
107*cdf0e10cSrcweir 				mnBitCount = ( mnBitCount <= 1 ) ? 1 :
108*cdf0e10cSrcweir 							 ( mnBitCount <= 4 ) ? 4 :
109*cdf0e10cSrcweir 							 ( mnBitCount <= 8 ) ? 8 : 24;
110*cdf0e10cSrcweir 			}
111*cdf0e10cSrcweir 		}
112*cdf0e10cSrcweir 		else
113*cdf0e10cSrcweir 		{
114*cdf0e10cSrcweir 			mhDDB = 0;
115*cdf0e10cSrcweir 			bRet = FALSE;
116*cdf0e10cSrcweir 		}
117*cdf0e10cSrcweir 	}
118*cdf0e10cSrcweir 	else
119*cdf0e10cSrcweir 		bRet = FALSE;
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir 	return bRet;
122*cdf0e10cSrcweir }
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir // ------------------------------------------------------------------
125*cdf0e10cSrcweir 
126*cdf0e10cSrcweir bool WinSalBitmap::Create( const Size& rSize, sal_uInt16 nBitCount, const BitmapPalette& rPal )
127*cdf0e10cSrcweir {
128*cdf0e10cSrcweir 	bool bRet = FALSE;
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir 	mhDIB = ImplCreateDIB( rSize, nBitCount, rPal );
131*cdf0e10cSrcweir 
132*cdf0e10cSrcweir 	if( mhDIB )
133*cdf0e10cSrcweir 	{
134*cdf0e10cSrcweir 		maSize = rSize;
135*cdf0e10cSrcweir 		mnBitCount = nBitCount;
136*cdf0e10cSrcweir 		bRet = TRUE;
137*cdf0e10cSrcweir 	}
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 	return bRet;
140*cdf0e10cSrcweir }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir // ------------------------------------------------------------------
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir bool WinSalBitmap::Create( const SalBitmap& rSSalBitmap )
145*cdf0e10cSrcweir {
146*cdf0e10cSrcweir 	bool bRet = FALSE;
147*cdf0e10cSrcweir     const WinSalBitmap& rSalBitmap = static_cast<const WinSalBitmap&>(rSSalBitmap);
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir 	if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB )
150*cdf0e10cSrcweir 	{
151*cdf0e10cSrcweir 		HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB,
152*cdf0e10cSrcweir 										   rSalBitmap.mhDIB != 0 );
153*cdf0e10cSrcweir 
154*cdf0e10cSrcweir 		if ( hNewHdl )
155*cdf0e10cSrcweir 		{
156*cdf0e10cSrcweir 			if( rSalBitmap.mhDIB )
157*cdf0e10cSrcweir 				mhDIB = (HGLOBAL) hNewHdl;
158*cdf0e10cSrcweir 			else if( rSalBitmap.mhDDB )
159*cdf0e10cSrcweir 				mhDDB = (HBITMAP) hNewHdl;
160*cdf0e10cSrcweir 
161*cdf0e10cSrcweir 			maSize = rSalBitmap.maSize;
162*cdf0e10cSrcweir 			mnBitCount = rSalBitmap.mnBitCount;
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 			bRet = TRUE;
165*cdf0e10cSrcweir 		}
166*cdf0e10cSrcweir 	}
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir 	return bRet;
169*cdf0e10cSrcweir }
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir // ------------------------------------------------------------------
172*cdf0e10cSrcweir 
173*cdf0e10cSrcweir bool WinSalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics )
174*cdf0e10cSrcweir {
175*cdf0e10cSrcweir 	bool bRet = FALSE;
176*cdf0e10cSrcweir 
177*cdf0e10cSrcweir     const WinSalBitmap& rSalBmp = static_cast<const WinSalBitmap&>(rSSalBmp);
178*cdf0e10cSrcweir     WinSalGraphics* pGraphics = static_cast<WinSalGraphics*>(pSGraphics);
179*cdf0e10cSrcweir 
180*cdf0e10cSrcweir 	if( rSalBmp.mhDIB )
181*cdf0e10cSrcweir 	{
182*cdf0e10cSrcweir 		PBITMAPINFO 		pBI = (PBITMAPINFO) GlobalLock( rSalBmp.mhDIB );
183*cdf0e10cSrcweir 		PBITMAPINFOHEADER	pBIH = (PBITMAPINFOHEADER) pBI;
184*cdf0e10cSrcweir 		HDC 				hDC  = pGraphics->mhDC;
185*cdf0e10cSrcweir 		HBITMAP 			hNewDDB;
186*cdf0e10cSrcweir 		BITMAP				aDDBInfo;
187*cdf0e10cSrcweir 		PBYTE				pBits = (PBYTE) pBI + *(DWORD*) pBI +
188*cdf0e10cSrcweir 							ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGBQUAD );
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 		if( pBIH->biBitCount == 1 )
191*cdf0e10cSrcweir 		{
192*cdf0e10cSrcweir 			hNewDDB = CreateBitmap( pBIH->biWidth, pBIH->biHeight, 1, 1, NULL );
193*cdf0e10cSrcweir 
194*cdf0e10cSrcweir 			if( hNewDDB )
195*cdf0e10cSrcweir 				SetDIBits( hDC, hNewDDB, 0, pBIH->biHeight, pBits, pBI, DIB_RGB_COLORS );
196*cdf0e10cSrcweir 		}
197*cdf0e10cSrcweir 		else
198*cdf0e10cSrcweir 			hNewDDB = CreateDIBitmap( hDC, (PBITMAPINFOHEADER) pBI, CBM_INIT, pBits, pBI, DIB_RGB_COLORS );
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 		GlobalUnlock( rSalBmp.mhDIB );
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 		if( hNewDDB && WIN_GetObject( hNewDDB, sizeof( BITMAP ), &aDDBInfo ) )
203*cdf0e10cSrcweir 		{
204*cdf0e10cSrcweir 			mhDDB = hNewDDB;
205*cdf0e10cSrcweir 			maSize = Size( aDDBInfo.bmWidth, aDDBInfo.bmHeight );
206*cdf0e10cSrcweir 			mnBitCount = aDDBInfo.bmPlanes * aDDBInfo.bmBitsPixel;
207*cdf0e10cSrcweir 
208*cdf0e10cSrcweir 			bRet = TRUE;
209*cdf0e10cSrcweir 		}
210*cdf0e10cSrcweir 		else if( hNewDDB )
211*cdf0e10cSrcweir 			DeleteObject( hNewDDB );
212*cdf0e10cSrcweir 	}
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir 	return bRet;
215*cdf0e10cSrcweir }
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir // ------------------------------------------------------------------
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir bool WinSalBitmap::Create( const SalBitmap& rSSalBmp, sal_uInt16 nNewBitCount )
220*cdf0e10cSrcweir {
221*cdf0e10cSrcweir 	bool bRet = FALSE;
222*cdf0e10cSrcweir 
223*cdf0e10cSrcweir     const WinSalBitmap& rSalBmp = static_cast<const WinSalBitmap&>(rSSalBmp);
224*cdf0e10cSrcweir 
225*cdf0e10cSrcweir 	if( rSalBmp.mhDDB )
226*cdf0e10cSrcweir 	{
227*cdf0e10cSrcweir 		mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() );
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 		if( mhDIB )
230*cdf0e10cSrcweir 		{
231*cdf0e10cSrcweir 			PBITMAPINFO pBI = (PBITMAPINFO) GlobalLock( mhDIB );
232*cdf0e10cSrcweir 			const int	nLines = (int) rSalBmp.maSize.Height();
233*cdf0e10cSrcweir 			HDC 		hDC = GetDC( 0 );
234*cdf0e10cSrcweir 			PBYTE		pBits = (PBYTE) pBI + *(DWORD*) pBI +
235*cdf0e10cSrcweir 								ImplGetDIBColorCount( mhDIB ) * sizeof( RGBQUAD );
236*cdf0e10cSrcweir 			SalData*	pSalData = GetSalData();
237*cdf0e10cSrcweir 			HPALETTE	hOldPal = 0;
238*cdf0e10cSrcweir 
239*cdf0e10cSrcweir 			if ( pSalData->mhDitherPal )
240*cdf0e10cSrcweir 			{
241*cdf0e10cSrcweir 				hOldPal = SelectPalette( hDC, pSalData->mhDitherPal, TRUE );
242*cdf0e10cSrcweir 				RealizePalette( hDC );
243*cdf0e10cSrcweir 			}
244*cdf0e10cSrcweir 
245*cdf0e10cSrcweir 			if( GetDIBits( hDC, rSalBmp.mhDDB, 0, nLines, pBits, pBI, DIB_RGB_COLORS ) == nLines )
246*cdf0e10cSrcweir 			{
247*cdf0e10cSrcweir 				GlobalUnlock( mhDIB );
248*cdf0e10cSrcweir 				maSize = rSalBmp.maSize;
249*cdf0e10cSrcweir 				mnBitCount = nNewBitCount;
250*cdf0e10cSrcweir 				bRet = TRUE;
251*cdf0e10cSrcweir 			}
252*cdf0e10cSrcweir 			else
253*cdf0e10cSrcweir 			{
254*cdf0e10cSrcweir 				GlobalUnlock( mhDIB );
255*cdf0e10cSrcweir 				GlobalFree( mhDIB );
256*cdf0e10cSrcweir 				mhDIB = 0;
257*cdf0e10cSrcweir 			}
258*cdf0e10cSrcweir 
259*cdf0e10cSrcweir 			if( hOldPal )
260*cdf0e10cSrcweir 				SelectPalette( hDC, hOldPal, TRUE );
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 			ReleaseDC( 0, hDC );
263*cdf0e10cSrcweir 		}
264*cdf0e10cSrcweir 	}
265*cdf0e10cSrcweir 
266*cdf0e10cSrcweir 	return bRet;
267*cdf0e10cSrcweir }
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir // ------------------------------------------------------------------
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir void WinSalBitmap::Destroy()
272*cdf0e10cSrcweir {
273*cdf0e10cSrcweir 	if( mhDIB )
274*cdf0e10cSrcweir 		GlobalFree( mhDIB );
275*cdf0e10cSrcweir 	else if( mhDDB )
276*cdf0e10cSrcweir 		DeleteObject( mhDDB );
277*cdf0e10cSrcweir 
278*cdf0e10cSrcweir 	maSize = Size();
279*cdf0e10cSrcweir 	mnBitCount = 0;
280*cdf0e10cSrcweir }
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir // ------------------------------------------------------------------
283*cdf0e10cSrcweir 
284*cdf0e10cSrcweir sal_uInt16 WinSalBitmap::ImplGetDIBColorCount( HGLOBAL hDIB )
285*cdf0e10cSrcweir {
286*cdf0e10cSrcweir 	sal_uInt16 nColors = 0;
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir 	if( hDIB )
289*cdf0e10cSrcweir 	{
290*cdf0e10cSrcweir 		PBITMAPINFO 		pBI = (PBITMAPINFO) GlobalLock( hDIB );
291*cdf0e10cSrcweir 		PBITMAPINFOHEADER	pBIH = (PBITMAPINFOHEADER) pBI;
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 		if ( pBIH->biSize != sizeof( BITMAPCOREHEADER ) )
294*cdf0e10cSrcweir 		{
295*cdf0e10cSrcweir 			if( pBIH->biBitCount <= 8 )
296*cdf0e10cSrcweir 			{
297*cdf0e10cSrcweir 				if ( pBIH->biClrUsed )
298*cdf0e10cSrcweir 					nColors = (sal_uInt16) pBIH->biClrUsed;
299*cdf0e10cSrcweir 				else
300*cdf0e10cSrcweir 					nColors = 1 << pBIH->biBitCount;
301*cdf0e10cSrcweir 			}
302*cdf0e10cSrcweir 		}
303*cdf0e10cSrcweir 		else if( ( (PBITMAPCOREHEADER) pBI )->bcBitCount <= 8 )
304*cdf0e10cSrcweir 			nColors = 1 << ( (PBITMAPCOREHEADER) pBI )->bcBitCount;
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir 		GlobalUnlock( hDIB );
307*cdf0e10cSrcweir 	}
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir 	return nColors;
310*cdf0e10cSrcweir }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir // ------------------------------------------------------------------
313*cdf0e10cSrcweir 
314*cdf0e10cSrcweir HGLOBAL WinSalBitmap::ImplCreateDIB( const Size& rSize, sal_uInt16 nBits, const BitmapPalette& rPal )
315*cdf0e10cSrcweir {
316*cdf0e10cSrcweir 	DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 16 || nBits == 24, "Unsupported BitCount!" );
317*cdf0e10cSrcweir 
318*cdf0e10cSrcweir 	HGLOBAL hDIB = 0;
319*cdf0e10cSrcweir 
320*cdf0e10cSrcweir 	if ( rSize.Width() && rSize.Height() )
321*cdf0e10cSrcweir 	{
322*cdf0e10cSrcweir 		const sal_uLong 	nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height();
323*cdf0e10cSrcweir 		const sal_uInt16	nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0;
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir 		hDIB = GlobalAlloc( GHND, sizeof( BITMAPINFOHEADER ) + nColors * sizeof( RGBQUAD ) + nImageSize );
326*cdf0e10cSrcweir 
327*cdf0e10cSrcweir 		if( hDIB )
328*cdf0e10cSrcweir 		{
329*cdf0e10cSrcweir 			PBITMAPINFO 		pBI = (PBITMAPINFO) GlobalLock( hDIB );
330*cdf0e10cSrcweir 			PBITMAPINFOHEADER	pBIH = (PBITMAPINFOHEADER) pBI;
331*cdf0e10cSrcweir 
332*cdf0e10cSrcweir 			pBIH->biSize = sizeof( BITMAPINFOHEADER );
333*cdf0e10cSrcweir 			pBIH->biWidth = rSize.Width();
334*cdf0e10cSrcweir 			pBIH->biHeight = rSize.Height();
335*cdf0e10cSrcweir 			pBIH->biPlanes = 1;
336*cdf0e10cSrcweir 			pBIH->biBitCount = nBits;
337*cdf0e10cSrcweir 			pBIH->biCompression = BI_RGB;
338*cdf0e10cSrcweir 			pBIH->biSizeImage = nImageSize;
339*cdf0e10cSrcweir 			pBIH->biXPelsPerMeter = 0;
340*cdf0e10cSrcweir 			pBIH->biYPelsPerMeter = 0;
341*cdf0e10cSrcweir 			pBIH->biClrUsed = 0;
342*cdf0e10cSrcweir 			pBIH->biClrImportant = 0;
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir 			if ( nColors )
345*cdf0e10cSrcweir 			{
346*cdf0e10cSrcweir 				const sal_uInt16 nMinCount = Min( nColors, rPal.GetEntryCount() );
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir 				if( nMinCount )
349*cdf0e10cSrcweir 					memcpy( pBI->bmiColors, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGBQUAD ) );
350*cdf0e10cSrcweir 			}
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir 			GlobalUnlock( hDIB );
353*cdf0e10cSrcweir 		}
354*cdf0e10cSrcweir 	}
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir 	return hDIB;
357*cdf0e10cSrcweir }
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir // ------------------------------------------------------------------
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir HANDLE WinSalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, bool bDIB )
362*cdf0e10cSrcweir {
363*cdf0e10cSrcweir 	HANDLE	hCopy = 0;
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 	if ( bDIB && hHdl )
366*cdf0e10cSrcweir 	{
367*cdf0e10cSrcweir 		const sal_uLong nSize = GlobalSize( hHdl );
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir 		if ( (hCopy = GlobalAlloc( GHND, nSize  )) != 0 )
370*cdf0e10cSrcweir 		{
371*cdf0e10cSrcweir 			memcpy( (LPSTR) GlobalLock( hCopy ), (LPSTR) GlobalLock( hHdl ), nSize );
372*cdf0e10cSrcweir 
373*cdf0e10cSrcweir 			GlobalUnlock( hCopy );
374*cdf0e10cSrcweir 			GlobalUnlock( hHdl );
375*cdf0e10cSrcweir 		}
376*cdf0e10cSrcweir 	}
377*cdf0e10cSrcweir 	else if ( hHdl )
378*cdf0e10cSrcweir 	{
379*cdf0e10cSrcweir 		BITMAP aBmp;
380*cdf0e10cSrcweir 
381*cdf0e10cSrcweir 		// Source-Bitmap nach Groesse befragen
382*cdf0e10cSrcweir 		WIN_GetObject( hHdl, sizeof( BITMAP ), (LPSTR) &aBmp );
383*cdf0e10cSrcweir 
384*cdf0e10cSrcweir 		// Destination-Bitmap erzeugen
385*cdf0e10cSrcweir 		if ( (hCopy = CreateBitmapIndirect( &aBmp )) != 0 )
386*cdf0e10cSrcweir 		{
387*cdf0e10cSrcweir 			HDC 	hBmpDC = CreateCompatibleDC( 0 );
388*cdf0e10cSrcweir 			HBITMAP hBmpOld = (HBITMAP) SelectObject( hBmpDC, hHdl );
389*cdf0e10cSrcweir 			HDC 	hCopyDC = CreateCompatibleDC( hBmpDC );
390*cdf0e10cSrcweir 			HBITMAP hCopyOld = (HBITMAP) SelectObject( hCopyDC, hCopy );
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir 			BitBlt( hCopyDC, 0, 0, aBmp.bmWidth, aBmp.bmHeight, hBmpDC, 0, 0, SRCCOPY );
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir 			SelectObject( hCopyDC, hCopyOld );
395*cdf0e10cSrcweir 			DeleteDC( hCopyDC );
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir 			SelectObject( hBmpDC, hBmpOld );
398*cdf0e10cSrcweir 			DeleteDC( hBmpDC );
399*cdf0e10cSrcweir 		}
400*cdf0e10cSrcweir 	}
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir 	return hCopy;
403*cdf0e10cSrcweir }
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir // ------------------------------------------------------------------
406*cdf0e10cSrcweir 
407*cdf0e10cSrcweir BitmapBuffer* WinSalBitmap::AcquireBuffer( bool /*bReadOnly*/ )
408*cdf0e10cSrcweir {
409*cdf0e10cSrcweir 	BitmapBuffer* pBuffer = NULL;
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir 	if( mhDIB )
412*cdf0e10cSrcweir 	{
413*cdf0e10cSrcweir 		PBITMAPINFO 		pBI = (PBITMAPINFO) GlobalLock( mhDIB );
414*cdf0e10cSrcweir 		PBITMAPINFOHEADER	pBIH = (PBITMAPINFOHEADER) pBI;
415*cdf0e10cSrcweir 
416*cdf0e10cSrcweir 		if( ( pBIH->biCompression == BI_RLE4 ) || ( pBIH->biCompression == BI_RLE8 ) )
417*cdf0e10cSrcweir 		{
418*cdf0e10cSrcweir 			Size	aSizePix( pBIH->biWidth, pBIH->biHeight );
419*cdf0e10cSrcweir 			HGLOBAL hNewDIB = ImplCreateDIB( aSizePix, pBIH->biBitCount, BitmapPalette() );
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir 			if( hNewDIB )
422*cdf0e10cSrcweir 			{
423*cdf0e10cSrcweir 				PBITMAPINFO 		pNewBI = (PBITMAPINFO) GlobalLock( hNewDIB );
424*cdf0e10cSrcweir 				PBITMAPINFOHEADER	pNewBIH = (PBITMAPINFOHEADER) pNewBI;
425*cdf0e10cSrcweir 				const sal_uInt16		nColorCount = ImplGetDIBColorCount( hNewDIB );
426*cdf0e10cSrcweir 				const sal_uLong 		nOffset = *(DWORD*) pBI + nColorCount * sizeof( RGBQUAD );
427*cdf0e10cSrcweir 				BYTE*				pOldBits = (PBYTE) pBI + nOffset;
428*cdf0e10cSrcweir 				BYTE*				pNewBits = (PBYTE) pNewBI + nOffset;
429*cdf0e10cSrcweir 
430*cdf0e10cSrcweir 				memcpy( pNewBI, pBI, nOffset );
431*cdf0e10cSrcweir 				pNewBIH->biCompression = 0;
432*cdf0e10cSrcweir 				ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->biCompression == BI_RLE4 );
433*cdf0e10cSrcweir 
434*cdf0e10cSrcweir 				GlobalUnlock( mhDIB );
435*cdf0e10cSrcweir 				GlobalFree( mhDIB );
436*cdf0e10cSrcweir 				mhDIB = hNewDIB;
437*cdf0e10cSrcweir 				pBI = pNewBI;
438*cdf0e10cSrcweir 				pBIH = pNewBIH;
439*cdf0e10cSrcweir 			}
440*cdf0e10cSrcweir 		}
441*cdf0e10cSrcweir 
442*cdf0e10cSrcweir 		if( pBIH->biPlanes == 1 )
443*cdf0e10cSrcweir 		{
444*cdf0e10cSrcweir 			pBuffer = new BitmapBuffer;
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir 			pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP |
447*cdf0e10cSrcweir 								( pBIH->biBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL :
448*cdf0e10cSrcweir 								  pBIH->biBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL :
449*cdf0e10cSrcweir 								  pBIH->biBitCount == 8 ? BMP_FORMAT_8BIT_PAL :
450*cdf0e10cSrcweir 								  pBIH->biBitCount == 16 ? BMP_FORMAT_16BIT_TC_LSB_MASK :
451*cdf0e10cSrcweir 								  pBIH->biBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR :
452*cdf0e10cSrcweir 								  pBIH->biBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL );
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir 			if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) )
455*cdf0e10cSrcweir 			{
456*cdf0e10cSrcweir 				pBuffer->mnWidth = maSize.Width();
457*cdf0e10cSrcweir 				pBuffer->mnHeight = maSize.Height();
458*cdf0e10cSrcweir 				pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->biBitCount );
459*cdf0e10cSrcweir 				pBuffer->mnBitCount = (sal_uInt16) pBIH->biBitCount;
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir 				if( pBuffer->mnBitCount <= 8 )
462*cdf0e10cSrcweir 				{
463*cdf0e10cSrcweir 					const sal_uInt16 nPalCount = ImplGetDIBColorCount( mhDIB );
464*cdf0e10cSrcweir 
465*cdf0e10cSrcweir 					pBuffer->maPalette.SetEntryCount( nPalCount );
466*cdf0e10cSrcweir 					memcpy( pBuffer->maPalette.ImplGetColorBuffer(), pBI->bmiColors, nPalCount * sizeof( RGBQUAD ) );
467*cdf0e10cSrcweir 					pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nPalCount * sizeof( RGBQUAD );
468*cdf0e10cSrcweir 				}
469*cdf0e10cSrcweir 				else if( ( pBIH->biBitCount == 16 ) || ( pBIH->biBitCount == 32 ) )
470*cdf0e10cSrcweir 				{
471*cdf0e10cSrcweir 					sal_uLong nOffset = 0UL;
472*cdf0e10cSrcweir 
473*cdf0e10cSrcweir 					if( pBIH->biCompression == BI_BITFIELDS )
474*cdf0e10cSrcweir 					{
475*cdf0e10cSrcweir 						nOffset = 3 * sizeof( RGBQUAD );
476*cdf0e10cSrcweir 						pBuffer->maColorMask = ColorMask( *(UINT32*) &pBI->bmiColors[ 0 ],
477*cdf0e10cSrcweir 														  *(UINT32*) &pBI->bmiColors[ 1 ],
478*cdf0e10cSrcweir 														  *(UINT32*) &pBI->bmiColors[ 2 ] );
479*cdf0e10cSrcweir 					}
480*cdf0e10cSrcweir 					else if( pBIH->biBitCount == 16 )
481*cdf0e10cSrcweir 						pBuffer->maColorMask = ColorMask( 0x00007c00UL, 0x000003e0UL, 0x0000001fUL );
482*cdf0e10cSrcweir 					else
483*cdf0e10cSrcweir 						pBuffer->maColorMask = ColorMask( 0x00ff0000UL, 0x0000ff00UL, 0x000000ffUL );
484*cdf0e10cSrcweir 
485*cdf0e10cSrcweir 					pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI + nOffset;
486*cdf0e10cSrcweir 				}
487*cdf0e10cSrcweir 				else
488*cdf0e10cSrcweir 					pBuffer->mpBits = (PBYTE) pBI + *(DWORD*) pBI;
489*cdf0e10cSrcweir 			}
490*cdf0e10cSrcweir 			else
491*cdf0e10cSrcweir 			{
492*cdf0e10cSrcweir 				GlobalUnlock( mhDIB );
493*cdf0e10cSrcweir 				delete pBuffer;
494*cdf0e10cSrcweir 				pBuffer = NULL;
495*cdf0e10cSrcweir 			}
496*cdf0e10cSrcweir 		}
497*cdf0e10cSrcweir 		else
498*cdf0e10cSrcweir 			GlobalUnlock( mhDIB );
499*cdf0e10cSrcweir 	}
500*cdf0e10cSrcweir 
501*cdf0e10cSrcweir 	return pBuffer;
502*cdf0e10cSrcweir }
503*cdf0e10cSrcweir 
504*cdf0e10cSrcweir // ------------------------------------------------------------------
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir void WinSalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
507*cdf0e10cSrcweir {
508*cdf0e10cSrcweir 	if( pBuffer )
509*cdf0e10cSrcweir 	{
510*cdf0e10cSrcweir 		if( mhDIB )
511*cdf0e10cSrcweir 		{
512*cdf0e10cSrcweir 			if( !bReadOnly && !!pBuffer->maPalette )
513*cdf0e10cSrcweir 			{
514*cdf0e10cSrcweir 				PBITMAPINFO 	pBI = (PBITMAPINFO) GlobalLock( mhDIB );
515*cdf0e10cSrcweir 				const sal_uInt16	nCount = pBuffer->maPalette.GetEntryCount();
516*cdf0e10cSrcweir 				const sal_uInt16	nDIBColorCount = ImplGetDIBColorCount( mhDIB );
517*cdf0e10cSrcweir 				memcpy( pBI->bmiColors, pBuffer->maPalette.ImplGetColorBuffer(), Min( nDIBColorCount, nCount ) * sizeof( RGBQUAD ) );
518*cdf0e10cSrcweir 				GlobalUnlock( mhDIB );
519*cdf0e10cSrcweir 			}
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir 			GlobalUnlock( mhDIB );
522*cdf0e10cSrcweir 		}
523*cdf0e10cSrcweir 
524*cdf0e10cSrcweir 		delete pBuffer;
525*cdf0e10cSrcweir 	}
526*cdf0e10cSrcweir }
527*cdf0e10cSrcweir 
528*cdf0e10cSrcweir // ------------------------------------------------------------------
529*cdf0e10cSrcweir 
530*cdf0e10cSrcweir void WinSalBitmap::ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf,
531*cdf0e10cSrcweir 									 const Size& rSizePixel, bool bRLE4 )
532*cdf0e10cSrcweir {
533*cdf0e10cSrcweir 	HPBYTE			pRLE = (HPBYTE) pSrcBuf;
534*cdf0e10cSrcweir 	HPBYTE			pDIB = (HPBYTE) pDstBuf;
535*cdf0e10cSrcweir 	HPBYTE			pRow = (HPBYTE) pDstBuf;
536*cdf0e10cSrcweir 	sal_uLong			nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) );
537*cdf0e10cSrcweir 	HPBYTE			pLast = pDIB + rSizePixel.Height() * nWidthAl - 1;
538*cdf0e10cSrcweir 	sal_uLong			nCountByte;
539*cdf0e10cSrcweir 	sal_uLong			nRunByte;
540*cdf0e10cSrcweir 	sal_uLong			nX = 0;
541*cdf0e10cSrcweir 	sal_uLong			i;
542*cdf0e10cSrcweir 	BYTE			cTmp;
543*cdf0e10cSrcweir 	bool			bEndDecoding = FALSE;
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir 	if( pRLE && pDIB )
546*cdf0e10cSrcweir 	{
547*cdf0e10cSrcweir 		do
548*cdf0e10cSrcweir 		{
549*cdf0e10cSrcweir 			if( ( nCountByte = *pRLE++ ) == 0 )
550*cdf0e10cSrcweir 			{
551*cdf0e10cSrcweir 				nRunByte = *pRLE++;
552*cdf0e10cSrcweir 
553*cdf0e10cSrcweir 				if( nRunByte > 2UL )
554*cdf0e10cSrcweir 				{
555*cdf0e10cSrcweir 					if( bRLE4 )
556*cdf0e10cSrcweir 					{
557*cdf0e10cSrcweir 						nCountByte = nRunByte >> 1UL;
558*cdf0e10cSrcweir 
559*cdf0e10cSrcweir 						for( i = 0; i < nCountByte; i++ )
560*cdf0e10cSrcweir 						{
561*cdf0e10cSrcweir 							cTmp = *pRLE++;
562*cdf0e10cSrcweir 							ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
563*cdf0e10cSrcweir 							ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
564*cdf0e10cSrcweir 						}
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir 						if( nRunByte & 1 )
567*cdf0e10cSrcweir 							ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 );
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir 						if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
570*cdf0e10cSrcweir 							pRLE++;
571*cdf0e10cSrcweir 					}
572*cdf0e10cSrcweir 					else
573*cdf0e10cSrcweir 					{
574*cdf0e10cSrcweir 						memcpy( &pDIB[ nX ], pRLE, nRunByte );
575*cdf0e10cSrcweir 						pRLE += nRunByte;
576*cdf0e10cSrcweir 						nX += nRunByte;
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir 						if( nRunByte & 1 )
579*cdf0e10cSrcweir 							pRLE++;
580*cdf0e10cSrcweir 					}
581*cdf0e10cSrcweir 				}
582*cdf0e10cSrcweir 				else if( !nRunByte )
583*cdf0e10cSrcweir 				{
584*cdf0e10cSrcweir 					pDIB = ( pRow += nWidthAl );
585*cdf0e10cSrcweir 					nX = 0UL;
586*cdf0e10cSrcweir 				}
587*cdf0e10cSrcweir 				else if( nRunByte == 1 )
588*cdf0e10cSrcweir 					bEndDecoding = TRUE;
589*cdf0e10cSrcweir 				else
590*cdf0e10cSrcweir 				{
591*cdf0e10cSrcweir 					nX += *pRLE++;
592*cdf0e10cSrcweir 					pDIB = ( pRow += ( *pRLE++ ) * nWidthAl );
593*cdf0e10cSrcweir 				}
594*cdf0e10cSrcweir 			}
595*cdf0e10cSrcweir 			else
596*cdf0e10cSrcweir 			{
597*cdf0e10cSrcweir 				cTmp = *pRLE++;
598*cdf0e10cSrcweir 
599*cdf0e10cSrcweir 				if( bRLE4 )
600*cdf0e10cSrcweir 				{
601*cdf0e10cSrcweir 					nRunByte = nCountByte >> 1;
602*cdf0e10cSrcweir 
603*cdf0e10cSrcweir 					for( i = 0; i < nRunByte; i++ )
604*cdf0e10cSrcweir 					{
605*cdf0e10cSrcweir 						ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
606*cdf0e10cSrcweir 						ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
607*cdf0e10cSrcweir 					}
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir 					if( nCountByte & 1 )
610*cdf0e10cSrcweir 						ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
611*cdf0e10cSrcweir 				}
612*cdf0e10cSrcweir 				else
613*cdf0e10cSrcweir 				{
614*cdf0e10cSrcweir 					for( i = 0; i < nCountByte; i++ )
615*cdf0e10cSrcweir 						pDIB[ nX++ ] = cTmp;
616*cdf0e10cSrcweir 				}
617*cdf0e10cSrcweir 			}
618*cdf0e10cSrcweir 		}
619*cdf0e10cSrcweir 		while( !bEndDecoding && ( pDIB <= pLast ) );
620*cdf0e10cSrcweir 	}
621*cdf0e10cSrcweir }
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir bool WinSalBitmap::GetSystemData( BitmapSystemData& rData )
624*cdf0e10cSrcweir {
625*cdf0e10cSrcweir     bool bRet = false;
626*cdf0e10cSrcweir     if( mhDIB || mhDDB )
627*cdf0e10cSrcweir     {
628*cdf0e10cSrcweir         bRet = true;
629*cdf0e10cSrcweir         rData.pDIB = mhDIB;
630*cdf0e10cSrcweir         rData.pDDB = mhDDB;
631*cdf0e10cSrcweir         const Size& rSize = GetSize ();
632*cdf0e10cSrcweir         rData.mnWidth = rSize.Width();
633*cdf0e10cSrcweir         rData.mnHeight = rSize.Height();
634*cdf0e10cSrcweir     }
635*cdf0e10cSrcweir     return bRet;
636*cdf0e10cSrcweir }
637