1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <svpm.h> 29 30 #define _SV_SALBMP_CXX 31 #include <rtl/alloc.h> 32 #include <vcl/salbtype.hxx> 33 #include <salgdi.h> 34 #include <saldata.hxx> 35 #include <salbmp.h> 36 #include <vcl/bitmap.hxx> // for BitmapSystemData 37 #include <string.h> 38 39 #ifndef __H_FT2LIB 40 #include <wingdi.h> 41 #include <ft2lib.h> 42 #endif 43 44 // ----------- 45 // - Inlines - 46 // ----------- 47 48 inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex ) 49 { 50 BYTE& rByte = pScanline[ nX >> 1 ]; 51 52 ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) : 53 ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) ); 54 } 55 56 // ------------- 57 // - Os2SalBitmap - 58 // ------------- 59 60 Os2SalBitmap::Os2SalBitmap() : 61 mhDIB ( 0 ), 62 mhDIB1Subst ( 0 ), 63 mhDDB ( 0 ), 64 mnBitCount ( 0 ) 65 { 66 } 67 68 // ------------------------------------------------------------------ 69 70 Os2SalBitmap::~Os2SalBitmap() 71 { 72 Destroy(); 73 } 74 75 // ------------------------------------------------------------------ 76 77 bool Os2SalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle ) 78 { 79 BOOL bRet = TRUE; 80 81 if( bDIB ) 82 mhDIB = (HANDLE) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap ); 83 else 84 mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap ); 85 86 if( mhDIB ) 87 { 88 // bitmap-header is the beginning of memory block 89 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) mhDIB; 90 91 maSize = Size( pBIH->cx, pBIH->cy ); 92 mnBitCount = pBIH->cBitCount; 93 94 if( mnBitCount ) 95 mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24; 96 } 97 else if( mhDDB ) 98 { 99 BITMAPINFOHEADER2 aDDBInfoHeader; 100 101 aDDBInfoHeader.cbFix = sizeof( aDDBInfoHeader ); 102 103 if( GpiQueryBitmapInfoHeader( mhDDB, &aDDBInfoHeader ) ) 104 { 105 maSize = Size( aDDBInfoHeader.cx, aDDBInfoHeader.cy ); 106 mnBitCount = aDDBInfoHeader.cPlanes * aDDBInfoHeader.cBitCount; 107 108 if( mnBitCount ) 109 { 110 mnBitCount = ( mnBitCount <= 1 ) ? 1 : 111 ( mnBitCount <= 4 ) ? 4 : 112 ( mnBitCount <= 8 ) ? 8 : 24; 113 } 114 } 115 else 116 { 117 mhDDB = 0; 118 bRet = FALSE; 119 } 120 121 } 122 else 123 bRet = FALSE; 124 125 return bRet; 126 } 127 128 // ------------------------------------------------------------------ 129 130 bool Os2SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal ) 131 { 132 bool bRet = FALSE; 133 134 mhDIB = ImplCreateDIB( rSize, nBitCount, rPal ); 135 136 if( mhDIB ) 137 { 138 maSize = rSize; 139 mnBitCount = nBitCount; 140 bRet = TRUE; 141 } 142 143 return bRet; 144 } 145 146 // ------------------------------------------------------------------ 147 148 bool Os2SalBitmap::Create( const SalBitmap& rSSalBitmap ) 149 { 150 bool bRet = FALSE; 151 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap); 152 153 if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB ) 154 { 155 HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB, 156 rSalBitmap.mhDIB != 0 ); 157 158 if( hNewHdl ) 159 { 160 if( rSalBitmap.mhDIB ) 161 mhDIB = (HANDLE) hNewHdl; 162 else if( rSalBitmap.mhDDB ) 163 mhDDB = (HBITMAP) hNewHdl; 164 165 maSize = rSalBitmap.maSize; 166 mnBitCount = rSalBitmap.mnBitCount; 167 bRet = TRUE; 168 } 169 } 170 171 return bRet; 172 } 173 174 // ------------------------------------------------------------------ 175 176 bool Os2SalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics ) 177 { 178 bool bRet = FALSE; 179 const Os2SalBitmap& rSalBmp = static_cast<const Os2SalBitmap&>(rSSalBmp); 180 Os2SalGraphics* pGraphics = static_cast<Os2SalGraphics*>(pSGraphics); 181 182 if( rSalBmp.mhDIB ) 183 { 184 HPS hPS = pGraphics->mhPS; 185 HBITMAP hNewDDB; 186 BITMAPINFOHEADER2 aInfoHeader; 187 const Size aSize( rSalBmp.GetSize() ); 188 long nFormat[ 2 ]; 189 190 memset( &aInfoHeader, 0, sizeof( aInfoHeader ) ); 191 aInfoHeader.cbFix = 16; 192 aInfoHeader.cx = aSize.Width(); 193 aInfoHeader.cy = aSize.Height(); 194 195 GpiQueryDeviceBitmapFormats( hPS, 2L, (PLONG) &nFormat ); 196 aInfoHeader.cPlanes = nFormat[ 0 ]; 197 aInfoHeader.cBitCount = nFormat[ 1 ]; 198 199 // ! wegen Postscript-Treiber 200 if( !aInfoHeader.cBitCount ) 201 aInfoHeader.cBitCount = 24; 202 else if( ( aInfoHeader.cPlanes == 1 ) && ( aInfoHeader.cBitCount == 1 ) ) 203 aInfoHeader.cBitCount = 4; 204 205 // BitCount == 1 ist wegen aller moeglichen Treiberfehler nicht moeglich 206 if( rSalBmp.GetBitCount() == 1 ) 207 { 208 HANDLE hTmp = ImplCreateDIB4FromDIB1( rSalBmp.mhDIB ); 209 PBYTE pBits = (PBYTE) hTmp + *(ULONG*) hTmp + ImplGetDIBColorCount( hTmp ) * sizeof( RGB2 ); 210 211 hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) hTmp ); 212 rtl_freeMemory( (void*)hTmp ); 213 } 214 else 215 { 216 PBYTE pBits = (PBYTE) rSalBmp.mhDIB + *(ULONG*) rSalBmp.mhDIB + ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGB2 ); 217 hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) rSalBmp.mhDIB ); 218 } 219 220 aInfoHeader.cbFix = sizeof( aInfoHeader ); 221 222 if( hNewDDB && GpiQueryBitmapInfoHeader( hNewDDB, &aInfoHeader ) ) 223 { 224 mhDDB = hNewDDB; 225 maSize = Size( aInfoHeader.cx, aInfoHeader.cy ); 226 mnBitCount = aInfoHeader.cPlanes * aInfoHeader.cBitCount; 227 228 if( mnBitCount ) 229 { 230 mnBitCount = ( mnBitCount <= 1 ) ? 1 : 231 ( mnBitCount <= 4 ) ? 4 : 232 ( mnBitCount <= 8 ) ? 8 : 24; 233 } 234 235 bRet = TRUE; 236 } 237 else if( hNewDDB ) 238 GpiDeleteBitmap( hNewDDB ); 239 } 240 241 return bRet; 242 } 243 244 // ------------------------------------------------------------------ 245 246 bool Os2SalBitmap::Create( const SalBitmap& rSSalBmp, USHORT nNewBitCount ) 247 { 248 bool bRet = FALSE; 249 const Os2SalBitmap& rSalBmp = static_cast<const Os2SalBitmap&>(rSSalBmp); 250 251 if( rSalBmp.mhDDB ) 252 { 253 mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() ); 254 255 if( mhDIB ) 256 { 257 // bitmap-header is the beginning of memory block 258 PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB; 259 const int nLines = (int) rSalBmp.maSize.Height(); 260 PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBI + ImplGetDIBColorCount( mhDIB ) * sizeof( RGB2 ); 261 SIZEL aSizeL = { rSalBmp.maSize.Width(), nLines }; 262 HAB hAB = GetSalData()->mhAB; 263 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL }; 264 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 265 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 266 HBITMAP hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, rSalBmp.mhDDB ); 267 268 if( GpiQueryBitmapBits( hMemPS, 0, nLines, pBits, pBI ) == nLines ) 269 { 270 maSize = rSalBmp.maSize; 271 mnBitCount = nNewBitCount; 272 bRet = TRUE; 273 } 274 else 275 { 276 rtl_freeMemory( (void*)mhDIB ); 277 mhDIB = 0; 278 } 279 280 Ft2SetBitmap( hMemPS, hMemOld ); 281 Ft2DestroyPS( hMemPS ); 282 DevCloseDC( hMemDC ); 283 } 284 } 285 286 return bRet; 287 } 288 289 // ------------------------------------------------------------------ 290 291 void Os2SalBitmap::Destroy() 292 { 293 if( mhDIB ) 294 rtl_freeMemory( (void*)mhDIB ); 295 else if( mhDDB ) 296 GpiDeleteBitmap( mhDDB ); 297 298 if( mhDIB1Subst ) 299 { 300 rtl_freeMemory( (void*)mhDIB1Subst ); 301 mhDIB1Subst = NULL; 302 } 303 304 maSize = Size(); 305 mnBitCount = 0; 306 } 307 308 // ------------------------------------------------------------------ 309 310 void Os2SalBitmap::ImplReplacehDIB1Subst( HANDLE hDIB1Subst ) 311 { 312 if( mhDIB1Subst ) 313 rtl_freeMemory( (void*)mhDIB1Subst ); 314 315 mhDIB1Subst = hDIB1Subst; 316 } 317 318 // ------------------------------------------------------------------ 319 320 USHORT Os2SalBitmap::ImplGetDIBColorCount( HANDLE hDIB ) 321 { 322 USHORT nColors = 0; 323 324 if( hDIB ) 325 { 326 // bitmap infos can be found at the beginning of the memory 327 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hDIB; 328 329 if( pBIH->cBitCount <= 8 ) 330 { 331 if( pBIH->cclrUsed ) 332 nColors = (USHORT) pBIH->cclrUsed; 333 else 334 nColors = 1 << pBIH->cBitCount; 335 } 336 } 337 338 return nColors; 339 } 340 341 // ------------------------------------------------------------------ 342 343 HANDLE Os2SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBits, const BitmapPalette& rPal ) 344 { 345 DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24, "Unsupported BitCount!" ); 346 347 HANDLE hDIB = 0; 348 349 if ( rSize.Width() && rSize.Height() && ( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24 ) ) 350 { 351 const ULONG nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height(); 352 const USHORT nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0; 353 354 hDIB = (HANDLE) rtl_allocateZeroMemory( sizeof( BITMAPINFOHEADER2 ) + nColors * sizeof( RGB2 ) + nImageSize ); 355 356 if( hDIB ) 357 { 358 // bitmap infos can be found at the beginning of the memory 359 PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB; 360 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI; 361 362 pBIH->cbFix = sizeof( BITMAPINFOHEADER2 ); 363 pBIH->cx = rSize.Width(); 364 pBIH->cy = rSize.Height(); 365 pBIH->cPlanes = 1; 366 pBIH->cBitCount = nBits; 367 pBIH->ulCompression = BCA_UNCOMP; // BI_RGB; 368 pBIH->cbImage = nImageSize; 369 pBIH->cxResolution = 0; 370 pBIH->cyResolution = 0; 371 pBIH->cclrUsed = 0; 372 pBIH->cclrImportant = 0; 373 374 // Rest auf 0 setzen 375 memset( (PBYTE) &pBIH->usUnits, 0, (PBYTE) pBI->argbColor - (PBYTE) &pBIH->usUnits ); 376 377 if( nColors ) 378 { 379 const USHORT nMinCount = Min( nColors, rPal.GetEntryCount() ); 380 381 if( nMinCount ) 382 memcpy( pBI->argbColor, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGB2 ) ); 383 } 384 } 385 } 386 387 return hDIB; 388 } 389 390 // ------------------------------------------------------------------ 391 392 HANDLE Os2SalBitmap::ImplCreateDIB4FromDIB1( HANDLE hDIB1 ) 393 { 394 PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB1; 395 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI; 396 PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBIH + Os2SalBitmap::ImplGetDIBColorCount( hDIB1 ) * sizeof( RGB2 ); 397 ULONG nWidth = pBIH->cx, nHeight = pBIH->cy; 398 ULONG nAligned = AlignedWidth4Bytes( nWidth ); 399 ULONG nAligned4 = AlignedWidth4Bytes( nWidth << 2 ); 400 ULONG nSize4 = sizeof( BITMAPINFOHEADER2 ) + ( sizeof( RGB2 ) << 4 ) + nAligned4 * nHeight; 401 PBYTE pDIB4 = (PBYTE) rtl_allocateZeroMemory( nSize4 ); 402 PBITMAPINFO2 pBI4 = (PBITMAPINFO2) pDIB4; 403 PBITMAPINFOHEADER2 pBIH4 = (PBITMAPINFOHEADER2) pBI4; 404 BYTE aMap[ 4 ] = { 0x00, 0x01, 0x10, 0x11 }; 405 406 memset( pBIH4, 0, sizeof( BITMAPINFOHEADER2 ) ); 407 pBIH4->cbFix = sizeof( BITMAPINFOHEADER2 ); 408 pBIH4->cx = nWidth; 409 pBIH4->cy = nHeight; 410 pBIH4->cPlanes = 1; 411 pBIH4->cBitCount = 4; 412 413 // die ersten beiden Eintraege der 1Bit-Farbtabelle kopieren 414 memcpy( pBI4->argbColor, pBI->argbColor, sizeof( RGB2 ) << 1 ); 415 416 PBYTE pBits4 = (PBYTE) pBI4 + *(ULONG*) pBIH4 + ( sizeof( RGB2 ) << 4 ); 417 418 // 4Bit-DIB-Bilddaten setzen 419 for( ULONG nY = 0UL; nY < nHeight; nY++ ) 420 { 421 PBYTE pTmp = pBits; pBits += nAligned; 422 PBYTE pTmp4 = pBits4; pBits4 += nAligned4; 423 424 for( ULONG nX = 0UL; nX < nWidth; nX += 8UL ) 425 { 426 *pTmp4++ = aMap[ ( *pTmp >> 6 ) & 3 ]; 427 *pTmp4++ = aMap[ ( *pTmp >> 4 ) & 3 ]; 428 *pTmp4++ = aMap[ ( *pTmp >> 2 ) & 3 ]; 429 *pTmp4++ = aMap[ *pTmp++ & 3 ]; 430 } 431 } 432 433 return (HANDLE) pDIB4; 434 } 435 436 // ------------------------------------------------------------------ 437 438 HANDLE Os2SalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, BOOL bDIB ) 439 { 440 HANDLE hCopy = 0; 441 442 if( bDIB && hHdl ) 443 { 444 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hHdl; 445 const ULONG nSize = sizeof( BITMAPINFOHEADER2 ) 446 + ImplGetDIBColorCount( hHdl ) * sizeof( RGB2 ) + 447 ( pBIH->cbImage ? pBIH->cbImage : AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) ); 448 449 BYTE* pCopy = (BYTE*)rtl_allocateZeroMemory( nSize ); 450 memcpy( pCopy, (BYTE*) hHdl, nSize ); 451 hCopy = (HANDLE) pCopy; 452 } 453 else if( hHdl ) 454 { 455 HAB hAB = GetSalData()->mhAB; 456 HDC hSrcMemDC; 457 HDC hDestMemDC; 458 HPS hSrcMemPS; 459 HPS hDestMemPS; 460 HBITMAP hCopyBitmap; 461 BITMAPINFOHEADER2 aInfoHeader; 462 DEVOPENSTRUC aDevOpenStruc; 463 SIZEL size; 464 465 aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 ); 466 GpiQueryBitmapInfoHeader( hHdl, &aInfoHeader ); 467 size.cx = aInfoHeader.cx; 468 size.cy = aInfoHeader.cy; 469 470 // Memory DCs erzeugen 471 aDevOpenStruc.pszLogAddress = 0; 472 aDevOpenStruc.pszDriverName = (PSZ)"DISPLAY"; 473 474 hSrcMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 475 hDestMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 ); 476 477 // Memory PSs erzeugen 478 hSrcMemPS = Ft2CreatePS( hAB, hSrcMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 479 hDestMemPS = Ft2CreatePS( hAB, hDestMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS ); 480 481 Ft2SetBitmap( hSrcMemPS, hHdl ); 482 483 if( !hHdl ) 484 { 485 memset( &aInfoHeader, 0, sizeof( BITMAPINFOHEADER2 ) ); 486 aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 ); 487 aInfoHeader.cx = 0; 488 aInfoHeader.cy = 0; 489 aInfoHeader.cPlanes = 1; 490 aInfoHeader.cBitCount = 1; 491 } 492 493 hCopy = GpiCreateBitmap( hDestMemPS, &aInfoHeader, 0, NULL, NULL ); 494 Ft2SetBitmap( hDestMemPS, hCopy ); 495 496 POINTL pts[3]; 497 498 pts[0].x = 0; 499 pts[0].y = 0; 500 pts[1].x = size.cx; 501 pts[1].y = size.cy; 502 pts[2].x = 0; 503 pts[2].y = 0; 504 505 GpiBitBlt( hDestMemPS, hSrcMemPS, 3, pts, ROP_SRCCOPY, BBO_IGNORE ); 506 507 Ft2SetBitmap( hSrcMemPS, (HBITMAP)0L); 508 Ft2SetBitmap( hDestMemPS, (HBITMAP)0L); 509 Ft2Associate( hSrcMemPS, NULLHANDLE ); 510 Ft2Associate( hDestMemPS, NULLHANDLE ); 511 Ft2DestroyPS( hSrcMemPS ); 512 Ft2DestroyPS( hDestMemPS ); 513 DevCloseDC( hSrcMemDC ); 514 DevCloseDC( hDestMemDC ); 515 } 516 517 return hCopy; 518 } 519 520 // ------------------------------------------------------------------ 521 522 BitmapBuffer* Os2SalBitmap::AcquireBuffer( bool bReadOnly ) 523 { 524 BitmapBuffer* pBuffer = NULL; 525 526 if( mhDIB ) 527 { 528 // bitmap infos can be found at the beginning of the memory 529 PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB; 530 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI; 531 532 if( ( pBIH->ulCompression == BCA_RLE4 ) || ( pBIH->ulCompression == BCA_RLE8 ) ) 533 { 534 Size aSizePix( pBIH->cx, pBIH->cy ); 535 HANDLE hNewDIB = ImplCreateDIB( aSizePix, pBIH->cBitCount, BitmapPalette() ); 536 537 if( hNewDIB ) 538 { 539 // bitmap infos can be found at the beginning of the memory 540 PBITMAPINFO2 pNewBI = (PBITMAPINFO2) hNewDIB; 541 PBITMAPINFOHEADER2 pNewBIH = (PBITMAPINFOHEADER2) pNewBI; 542 const USHORT nColorCount = ImplGetDIBColorCount( hNewDIB ); 543 const ULONG nOffset = *(ULONG*) pBI + nColorCount * sizeof( RGB2 ); 544 BYTE* pOldBits = (BYTE*) pBI + nOffset; 545 BYTE* pNewBits = (BYTE*) pNewBI + nOffset; 546 547 memcpy( pNewBI, pBI, nOffset ); 548 pNewBIH->ulCompression = 0; 549 ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->ulCompression == BCA_RLE4 ); 550 551 rtl_freeMemory( (void*)mhDIB ); 552 553 mhDIB = hNewDIB; 554 pBI = pNewBI; 555 pBIH = pNewBIH; 556 } 557 } 558 559 if( pBIH->cPlanes == 1 ) 560 { 561 pBuffer = new BitmapBuffer; 562 563 pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP | 564 ( pBIH->cBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL : 565 pBIH->cBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL : 566 pBIH->cBitCount == 8 ? BMP_FORMAT_8BIT_PAL : 567 pBIH->cBitCount == 16 ? BMP_FORMAT_16BIT_TC_LSB_MASK : 568 pBIH->cBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR : 569 pBIH->cBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL ); 570 571 if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) ) 572 { 573 pBuffer->mnWidth = maSize.Width(); 574 pBuffer->mnHeight = maSize.Height(); 575 pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->cBitCount ); 576 pBuffer->mnBitCount = (USHORT) pBIH->cBitCount; 577 578 if( pBuffer->mnBitCount <= 8 ) 579 { 580 const USHORT nPalCount = ImplGetDIBColorCount( mhDIB ); 581 582 pBuffer->maPalette.SetEntryCount( nPalCount ); 583 584 if( nPalCount ) 585 memcpy( pBuffer->maPalette.ImplGetColorBuffer(), pBI->argbColor, nPalCount * sizeof( RGB2 ) ); 586 587 pBuffer->mpBits = (BYTE*) pBI + *(ULONG*) pBI + nPalCount * sizeof( RGB2 ); 588 } 589 else 590 pBuffer->mpBits = (BYTE*) pBI + *(ULONG*) pBI; 591 } 592 else 593 { 594 delete pBuffer; 595 pBuffer = NULL; 596 } 597 } 598 } 599 600 if( pBuffer && mhDIB1Subst ) 601 { 602 rtl_freeMemory( (void*)mhDIB1Subst ); 603 mhDIB1Subst = 0; 604 } 605 606 return pBuffer; 607 } 608 609 // ------------------------------------------------------------------ 610 611 void Os2SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly ) 612 { 613 if( pBuffer ) 614 { 615 if( mhDIB ) 616 { 617 if( !bReadOnly && !!pBuffer->maPalette ) 618 { 619 // bitmap infos can be found at the beginning of the memory 620 PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB; 621 const USHORT nCount = pBuffer->maPalette.GetEntryCount(); 622 623 if( nCount ) 624 memcpy( pBI->argbColor, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGB2 ) ); 625 } 626 } 627 628 delete pBuffer; 629 } 630 } 631 632 // ------------------------------------------------------------------ 633 634 void Os2SalBitmap::ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf, 635 const Size& rSizePixel, BOOL bRLE4 ) 636 { 637 HPBYTE pRLE = (HPBYTE) pSrcBuf; 638 HPBYTE pDIB = (HPBYTE) pDstBuf; 639 HPBYTE pRow = (HPBYTE) pDstBuf; 640 ULONG nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) ); 641 HPBYTE pLast = pDIB + rSizePixel.Height() * nWidthAl - 1; 642 ULONG nCountByte; 643 ULONG nRunByte; 644 ULONG nX = 0; 645 ULONG i; 646 BYTE cTmp; 647 BOOL bEndDecoding = FALSE; 648 649 if( pRLE && pDIB ) 650 { 651 do 652 { 653 if( !( nCountByte = *pRLE++ ) ) 654 { 655 nRunByte = *pRLE++; 656 657 if( nRunByte > 2UL ) 658 { 659 if( bRLE4 ) 660 { 661 nCountByte = nRunByte >> 1UL; 662 663 for( i = 0; i < nCountByte; i++ ) 664 { 665 cTmp = *pRLE++; 666 ImplSetPixel4( pDIB, nX++, cTmp >> 4 ); 667 ImplSetPixel4( pDIB, nX++, cTmp & 0x0f ); 668 } 669 670 if( nRunByte & 1 ) 671 ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 ); 672 673 if( ( ( nRunByte + 1 ) >> 1 ) & 1 ) 674 pRLE++; 675 } 676 else 677 { 678 memcpy( &pDIB[ nX ], pRLE, nRunByte ); 679 pRLE += nRunByte; 680 nX += nRunByte; 681 682 if( nRunByte & 1 ) 683 pRLE++; 684 } 685 } 686 else if( !nRunByte ) 687 { 688 pDIB = ( pRow += nWidthAl ); 689 nX = 0UL; 690 } 691 else if( nRunByte == 1 ) 692 bEndDecoding = TRUE; 693 else 694 { 695 nX += *pRLE++; 696 pDIB = ( pRow += ( *pRLE++ ) * nWidthAl ); 697 } 698 } 699 else 700 { 701 cTmp = *pRLE++; 702 703 if( bRLE4 ) 704 { 705 nRunByte = nCountByte >> 1; 706 707 for( i = 0; i < nRunByte; i++ ) 708 { 709 ImplSetPixel4( pDIB, nX++, cTmp >> 4 ); 710 ImplSetPixel4( pDIB, nX++, cTmp & 0x0f ); 711 } 712 713 if( nCountByte & 1 ) 714 ImplSetPixel4( pDIB, nX++, cTmp >> 4 ); 715 } 716 else 717 { 718 for( i = 0; i < nCountByte; i++ ) 719 pDIB[ nX++ ] = cTmp; 720 } 721 } 722 } 723 while( !bEndDecoding && ( pDIB <= pLast ) ); 724 } 725 } 726 727 bool Os2SalBitmap::GetSystemData( BitmapSystemData& rData ) 728 { 729 bool bRet = false; 730 if( mhDIB || mhDDB ) 731 { 732 bRet = true; 733 rData.pDIB = (void*)mhDIB; 734 rData.pDDB = (void*)mhDDB; 735 } 736 return bRet; 737 } 738