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