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