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