merge the formfield patch from ooo-build
[ooovba.git] / vcl / os2 / source / gdi / salbmp.cxx
blob9c4e628bb3300ef59f99853284e7554e0732fbf2
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: salbmp.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include <svpm.h>
33 #define _SV_SALBMP_CXX
34 #include <rtl/alloc.h>
35 #include <vcl/salbtype.hxx>
36 #include <salgdi.h>
37 #include <saldata.hxx>
38 #include <salbmp.h>
39 #include <vcl/bitmap.hxx> // for BitmapSystemData
40 #include <string.h>
42 #ifndef __H_FT2LIB
43 #include <wingdi.h>
44 #include <ft2lib.h>
45 #endif
47 // -----------
48 // - Inlines -
49 // -----------
51 inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const BYTE cIndex )
53 BYTE& rByte = pScanline[ nX >> 1 ];
55 ( nX & 1 ) ? ( rByte &= 0xf0, rByte |= ( cIndex & 0x0f ) ) :
56 ( rByte &= 0x0f, rByte |= ( cIndex << 4 ) );
59 // -------------
60 // - Os2SalBitmap -
61 // -------------
63 Os2SalBitmap::Os2SalBitmap() :
64 mhDIB ( 0 ),
65 mhDIB1Subst ( 0 ),
66 mhDDB ( 0 ),
67 mnBitCount ( 0 )
71 // ------------------------------------------------------------------
73 Os2SalBitmap::~Os2SalBitmap()
75 Destroy();
78 // ------------------------------------------------------------------
80 bool Os2SalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle )
82 BOOL bRet = TRUE;
84 if( bDIB )
85 mhDIB = (HANDLE) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, TRUE ) : hBitmap );
86 else
87 mhDDB = (HBITMAP) ( bCopyHandle ? ImplCopyDIBOrDDB( hBitmap, FALSE ) : hBitmap );
89 if( mhDIB )
91 // bitmap-header is the beginning of memory block
92 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) mhDIB;
94 maSize = Size( pBIH->cx, pBIH->cy );
95 mnBitCount = pBIH->cBitCount;
97 if( mnBitCount )
98 mnBitCount = ( mnBitCount <= 1 ) ? 1 : ( mnBitCount <= 4 ) ? 4 : ( mnBitCount <= 8 ) ? 8 : 24;
100 else if( mhDDB )
102 BITMAPINFOHEADER2 aDDBInfoHeader;
104 aDDBInfoHeader.cbFix = sizeof( aDDBInfoHeader );
106 if( GpiQueryBitmapInfoHeader( mhDDB, &aDDBInfoHeader ) )
108 maSize = Size( aDDBInfoHeader.cx, aDDBInfoHeader.cy );
109 mnBitCount = aDDBInfoHeader.cPlanes * aDDBInfoHeader.cBitCount;
111 if( mnBitCount )
113 mnBitCount = ( mnBitCount <= 1 ) ? 1 :
114 ( mnBitCount <= 4 ) ? 4 :
115 ( mnBitCount <= 8 ) ? 8 : 24;
118 else
120 mhDDB = 0;
121 bRet = FALSE;
125 else
126 bRet = FALSE;
128 return bRet;
131 // ------------------------------------------------------------------
133 bool Os2SalBitmap::Create( const Size& rSize, USHORT nBitCount, const BitmapPalette& rPal )
135 bool bRet = FALSE;
137 mhDIB = ImplCreateDIB( rSize, nBitCount, rPal );
139 if( mhDIB )
141 maSize = rSize;
142 mnBitCount = nBitCount;
143 bRet = TRUE;
146 return bRet;
149 // ------------------------------------------------------------------
151 bool Os2SalBitmap::Create( const SalBitmap& rSSalBitmap )
153 bool bRet = FALSE;
154 const Os2SalBitmap& rSalBitmap = static_cast<const Os2SalBitmap&>(rSSalBitmap);
156 if ( rSalBitmap.mhDIB || rSalBitmap.mhDDB )
158 HANDLE hNewHdl = ImplCopyDIBOrDDB( rSalBitmap.mhDIB ? rSalBitmap.mhDIB : rSalBitmap.mhDDB,
159 rSalBitmap.mhDIB != 0 );
161 if( hNewHdl )
163 if( rSalBitmap.mhDIB )
164 mhDIB = (HANDLE) hNewHdl;
165 else if( rSalBitmap.mhDDB )
166 mhDDB = (HBITMAP) hNewHdl;
168 maSize = rSalBitmap.maSize;
169 mnBitCount = rSalBitmap.mnBitCount;
170 bRet = TRUE;
174 return bRet;
177 // ------------------------------------------------------------------
179 bool Os2SalBitmap::Create( const SalBitmap& rSSalBmp, SalGraphics* pSGraphics )
181 bool bRet = FALSE;
182 const Os2SalBitmap& rSalBmp = static_cast<const Os2SalBitmap&>(rSSalBmp);
183 Os2SalGraphics* pGraphics = static_cast<Os2SalGraphics*>(pSGraphics);
185 if( rSalBmp.mhDIB )
187 HPS hPS = pGraphics->mhPS;
188 HBITMAP hNewDDB;
189 BITMAPINFOHEADER2 aInfoHeader;
190 const Size aSize( rSalBmp.GetSize() );
191 long nFormat[ 2 ];
193 memset( &aInfoHeader, 0, sizeof( aInfoHeader ) );
194 aInfoHeader.cbFix = 16;
195 aInfoHeader.cx = aSize.Width();
196 aInfoHeader.cy = aSize.Height();
198 GpiQueryDeviceBitmapFormats( hPS, 2L, (PLONG) &nFormat );
199 aInfoHeader.cPlanes = nFormat[ 0 ];
200 aInfoHeader.cBitCount = nFormat[ 1 ];
202 // ! wegen Postscript-Treiber
203 if( !aInfoHeader.cBitCount )
204 aInfoHeader.cBitCount = 24;
205 else if( ( aInfoHeader.cPlanes == 1 ) && ( aInfoHeader.cBitCount == 1 ) )
206 aInfoHeader.cBitCount = 4;
208 // BitCount == 1 ist wegen aller moeglichen Treiberfehler nicht moeglich
209 if( rSalBmp.GetBitCount() == 1 )
211 HANDLE hTmp = ImplCreateDIB4FromDIB1( rSalBmp.mhDIB );
212 PBYTE pBits = (PBYTE) hTmp + *(ULONG*) hTmp + ImplGetDIBColorCount( hTmp ) * sizeof( RGB2 );
214 hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) hTmp );
215 rtl_freeMemory( (void*)hTmp );
217 else
219 PBYTE pBits = (PBYTE) rSalBmp.mhDIB + *(ULONG*) rSalBmp.mhDIB + ImplGetDIBColorCount( rSalBmp.mhDIB ) * sizeof( RGB2 );
220 hNewDDB = GpiCreateBitmap( hPS, &aInfoHeader, CBM_INIT, pBits, (PBITMAPINFO2) rSalBmp.mhDIB );
223 aInfoHeader.cbFix = sizeof( aInfoHeader );
225 if( hNewDDB && GpiQueryBitmapInfoHeader( hNewDDB, &aInfoHeader ) )
227 mhDDB = hNewDDB;
228 maSize = Size( aInfoHeader.cx, aInfoHeader.cy );
229 mnBitCount = aInfoHeader.cPlanes * aInfoHeader.cBitCount;
231 if( mnBitCount )
233 mnBitCount = ( mnBitCount <= 1 ) ? 1 :
234 ( mnBitCount <= 4 ) ? 4 :
235 ( mnBitCount <= 8 ) ? 8 : 24;
238 bRet = TRUE;
240 else if( hNewDDB )
241 GpiDeleteBitmap( hNewDDB );
244 return bRet;
247 // ------------------------------------------------------------------
249 bool Os2SalBitmap::Create( const SalBitmap& rSSalBmp, USHORT nNewBitCount )
251 bool bRet = FALSE;
252 const Os2SalBitmap& rSalBmp = static_cast<const Os2SalBitmap&>(rSSalBmp);
254 if( rSalBmp.mhDDB )
256 mhDIB = ImplCreateDIB( rSalBmp.maSize, nNewBitCount, BitmapPalette() );
258 if( mhDIB )
260 // bitmap-header is the beginning of memory block
261 PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB;
262 const int nLines = (int) rSalBmp.maSize.Height();
263 PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBI + ImplGetDIBColorCount( mhDIB ) * sizeof( RGB2 );
264 SIZEL aSizeL = { rSalBmp.maSize.Width(), nLines };
265 HAB hAB = GetSalData()->mhAB;
266 DEVOPENSTRUC aDevOpenStruc = { NULL, (PSZ)"DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL };
267 HDC hMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 5L, (PDEVOPENDATA)&aDevOpenStruc, 0 );
268 HPS hMemPS = Ft2CreatePS( hAB, hMemDC, &aSizeL, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
269 HBITMAP hMemOld = (HBITMAP) Ft2SetBitmap( hMemPS, rSalBmp.mhDDB );
271 if( GpiQueryBitmapBits( hMemPS, 0, nLines, pBits, pBI ) == nLines )
273 maSize = rSalBmp.maSize;
274 mnBitCount = nNewBitCount;
275 bRet = TRUE;
277 else
279 rtl_freeMemory( (void*)mhDIB );
280 mhDIB = 0;
283 Ft2SetBitmap( hMemPS, hMemOld );
284 Ft2DestroyPS( hMemPS );
285 DevCloseDC( hMemDC );
289 return bRet;
292 // ------------------------------------------------------------------
294 void Os2SalBitmap::Destroy()
296 if( mhDIB )
297 rtl_freeMemory( (void*)mhDIB );
298 else if( mhDDB )
299 GpiDeleteBitmap( mhDDB );
301 if( mhDIB1Subst )
303 rtl_freeMemory( (void*)mhDIB1Subst );
304 mhDIB1Subst = NULL;
307 maSize = Size();
308 mnBitCount = 0;
311 // ------------------------------------------------------------------
313 void Os2SalBitmap::ImplReplacehDIB1Subst( HANDLE hDIB1Subst )
315 if( mhDIB1Subst )
316 rtl_freeMemory( (void*)mhDIB1Subst );
318 mhDIB1Subst = hDIB1Subst;
321 // ------------------------------------------------------------------
323 USHORT Os2SalBitmap::ImplGetDIBColorCount( HANDLE hDIB )
325 USHORT nColors = 0;
327 if( hDIB )
329 // bitmap infos can be found at the beginning of the memory
330 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hDIB;
332 if( pBIH->cBitCount <= 8 )
334 if( pBIH->cclrUsed )
335 nColors = (USHORT) pBIH->cclrUsed;
336 else
337 nColors = 1 << pBIH->cBitCount;
341 return nColors;
344 // ------------------------------------------------------------------
346 HANDLE Os2SalBitmap::ImplCreateDIB( const Size& rSize, USHORT nBits, const BitmapPalette& rPal )
348 DBG_ASSERT( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24, "Unsupported BitCount!" );
350 HANDLE hDIB = 0;
352 if ( rSize.Width() && rSize.Height() && ( nBits == 1 || nBits == 4 || nBits == 8 || nBits == 24 ) )
354 const ULONG nImageSize = AlignedWidth4Bytes( nBits * rSize.Width() ) * rSize.Height();
355 const USHORT nColors = ( nBits <= 8 ) ? ( 1 << nBits ) : 0;
357 hDIB = (HANDLE) rtl_allocateZeroMemory( sizeof( BITMAPINFOHEADER2 ) + nColors * sizeof( RGB2 ) + nImageSize );
359 if( hDIB )
361 // bitmap infos can be found at the beginning of the memory
362 PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB;
363 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI;
365 pBIH->cbFix = sizeof( BITMAPINFOHEADER2 );
366 pBIH->cx = rSize.Width();
367 pBIH->cy = rSize.Height();
368 pBIH->cPlanes = 1;
369 pBIH->cBitCount = nBits;
370 pBIH->ulCompression = BCA_UNCOMP; // BI_RGB;
371 pBIH->cbImage = nImageSize;
372 pBIH->cxResolution = 0;
373 pBIH->cyResolution = 0;
374 pBIH->cclrUsed = 0;
375 pBIH->cclrImportant = 0;
377 // Rest auf 0 setzen
378 memset( (PBYTE) &pBIH->usUnits, 0, (PBYTE) pBI->argbColor - (PBYTE) &pBIH->usUnits );
380 if( nColors )
382 const USHORT nMinCount = Min( nColors, rPal.GetEntryCount() );
384 if( nMinCount )
385 memcpy( pBI->argbColor, rPal.ImplGetColorBuffer(), nMinCount * sizeof( RGB2 ) );
390 return hDIB;
393 // ------------------------------------------------------------------
395 HANDLE Os2SalBitmap::ImplCreateDIB4FromDIB1( HANDLE hDIB1 )
397 PBITMAPINFO2 pBI = (PBITMAPINFO2) hDIB1;
398 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI;
399 PBYTE pBits = (PBYTE) pBI + *(ULONG*) pBIH + Os2SalBitmap::ImplGetDIBColorCount( hDIB1 ) * sizeof( RGB2 );
400 ULONG nWidth = pBIH->cx, nHeight = pBIH->cy;
401 ULONG nAligned = AlignedWidth4Bytes( nWidth );
402 ULONG nAligned4 = AlignedWidth4Bytes( nWidth << 2 );
403 ULONG nSize4 = sizeof( BITMAPINFOHEADER2 ) + ( sizeof( RGB2 ) << 4 ) + nAligned4 * nHeight;
404 PBYTE pDIB4 = (PBYTE) rtl_allocateZeroMemory( nSize4 );
405 PBITMAPINFO2 pBI4 = (PBITMAPINFO2) pDIB4;
406 PBITMAPINFOHEADER2 pBIH4 = (PBITMAPINFOHEADER2) pBI4;
407 BYTE aMap[ 4 ] = { 0x00, 0x01, 0x10, 0x11 };
409 memset( pBIH4, 0, sizeof( BITMAPINFOHEADER2 ) );
410 pBIH4->cbFix = sizeof( BITMAPINFOHEADER2 );
411 pBIH4->cx = nWidth;
412 pBIH4->cy = nHeight;
413 pBIH4->cPlanes = 1;
414 pBIH4->cBitCount = 4;
416 // die ersten beiden Eintraege der 1Bit-Farbtabelle kopieren
417 memcpy( pBI4->argbColor, pBI->argbColor, sizeof( RGB2 ) << 1 );
419 PBYTE pBits4 = (PBYTE) pBI4 + *(ULONG*) pBIH4 + ( sizeof( RGB2 ) << 4 );
421 // 4Bit-DIB-Bilddaten setzen
422 for( ULONG nY = 0UL; nY < nHeight; nY++ )
424 PBYTE pTmp = pBits; pBits += nAligned;
425 PBYTE pTmp4 = pBits4; pBits4 += nAligned4;
427 for( ULONG nX = 0UL; nX < nWidth; nX += 8UL )
429 *pTmp4++ = aMap[ ( *pTmp >> 6 ) & 3 ];
430 *pTmp4++ = aMap[ ( *pTmp >> 4 ) & 3 ];
431 *pTmp4++ = aMap[ ( *pTmp >> 2 ) & 3 ];
432 *pTmp4++ = aMap[ *pTmp++ & 3 ];
436 return (HANDLE) pDIB4;
439 // ------------------------------------------------------------------
441 HANDLE Os2SalBitmap::ImplCopyDIBOrDDB( HANDLE hHdl, BOOL bDIB )
443 HANDLE hCopy = 0;
445 if( bDIB && hHdl )
447 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) hHdl;
448 const ULONG nSize = sizeof( BITMAPINFOHEADER2 )
449 + ImplGetDIBColorCount( hHdl ) * sizeof( RGB2 ) +
450 ( pBIH->cbImage ? pBIH->cbImage : AlignedWidth4Bytes( pBIH->cx * pBIH->cBitCount ) );
452 BYTE* pCopy = (BYTE*)rtl_allocateZeroMemory( nSize );
453 memcpy( pCopy, (BYTE*) hHdl, nSize );
454 hCopy = (HANDLE) pCopy;
456 else if( hHdl )
458 HAB hAB = GetSalData()->mhAB;
459 HDC hSrcMemDC;
460 HDC hDestMemDC;
461 HPS hSrcMemPS;
462 HPS hDestMemPS;
463 HBITMAP hCopyBitmap;
464 BITMAPINFOHEADER2 aInfoHeader;
465 DEVOPENSTRUC aDevOpenStruc;
466 SIZEL size;
468 aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 );
469 GpiQueryBitmapInfoHeader( hHdl, &aInfoHeader );
470 size.cx = aInfoHeader.cx;
471 size.cy = aInfoHeader.cy;
473 // Memory DCs erzeugen
474 aDevOpenStruc.pszLogAddress = 0;
475 aDevOpenStruc.pszDriverName = (PSZ)"DISPLAY";
477 hSrcMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 );
478 hDestMemDC = DevOpenDC( hAB, OD_MEMORY, (PSZ)"*", 2, (PDEVOPENDATA)&aDevOpenStruc, 0 );
480 // Memory PSs erzeugen
481 hSrcMemPS = Ft2CreatePS( hAB, hSrcMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
482 hDestMemPS = Ft2CreatePS( hAB, hDestMemDC, &size, GPIT_MICRO | GPIA_ASSOC | PU_PELS );
484 Ft2SetBitmap( hSrcMemPS, hHdl );
486 if( !hHdl )
488 memset( &aInfoHeader, 0, sizeof( BITMAPINFOHEADER2 ) );
489 aInfoHeader.cbFix = sizeof( BITMAPINFOHEADER2 );
490 aInfoHeader.cx = 0;
491 aInfoHeader.cy = 0;
492 aInfoHeader.cPlanes = 1;
493 aInfoHeader.cBitCount = 1;
496 hCopy = GpiCreateBitmap( hDestMemPS, &aInfoHeader, 0, NULL, NULL );
497 Ft2SetBitmap( hDestMemPS, hCopy );
499 POINTL pts[3];
501 pts[0].x = 0;
502 pts[0].y = 0;
503 pts[1].x = size.cx;
504 pts[1].y = size.cy;
505 pts[2].x = 0;
506 pts[2].y = 0;
508 GpiBitBlt( hDestMemPS, hSrcMemPS, 3, pts, ROP_SRCCOPY, BBO_IGNORE );
510 Ft2SetBitmap( hSrcMemPS, (HBITMAP)0L);
511 Ft2SetBitmap( hDestMemPS, (HBITMAP)0L);
512 Ft2Associate( hSrcMemPS, NULLHANDLE );
513 Ft2Associate( hDestMemPS, NULLHANDLE );
514 Ft2DestroyPS( hSrcMemPS );
515 Ft2DestroyPS( hDestMemPS );
516 DevCloseDC( hSrcMemDC );
517 DevCloseDC( hDestMemDC );
520 return hCopy;
523 // ------------------------------------------------------------------
525 BitmapBuffer* Os2SalBitmap::AcquireBuffer( bool bReadOnly )
527 BitmapBuffer* pBuffer = NULL;
529 if( mhDIB )
531 // bitmap infos can be found at the beginning of the memory
532 PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB;
533 PBITMAPINFOHEADER2 pBIH = (PBITMAPINFOHEADER2) pBI;
535 if( ( pBIH->ulCompression == BCA_RLE4 ) || ( pBIH->ulCompression == BCA_RLE8 ) )
537 Size aSizePix( pBIH->cx, pBIH->cy );
538 HANDLE hNewDIB = ImplCreateDIB( aSizePix, pBIH->cBitCount, BitmapPalette() );
540 if( hNewDIB )
542 // bitmap infos can be found at the beginning of the memory
543 PBITMAPINFO2 pNewBI = (PBITMAPINFO2) hNewDIB;
544 PBITMAPINFOHEADER2 pNewBIH = (PBITMAPINFOHEADER2) pNewBI;
545 const USHORT nColorCount = ImplGetDIBColorCount( hNewDIB );
546 const ULONG nOffset = *(ULONG*) pBI + nColorCount * sizeof( RGB2 );
547 BYTE* pOldBits = (BYTE*) pBI + nOffset;
548 BYTE* pNewBits = (BYTE*) pNewBI + nOffset;
550 memcpy( pNewBI, pBI, nOffset );
551 pNewBIH->ulCompression = 0;
552 ImplDecodeRLEBuffer( pOldBits, pNewBits, aSizePix, pBIH->ulCompression == BCA_RLE4 );
554 rtl_freeMemory( (void*)mhDIB );
556 mhDIB = hNewDIB;
557 pBI = pNewBI;
558 pBIH = pNewBIH;
562 if( pBIH->cPlanes == 1 )
564 pBuffer = new BitmapBuffer;
566 pBuffer->mnFormat = BMP_FORMAT_BOTTOM_UP |
567 ( pBIH->cBitCount == 1 ? BMP_FORMAT_1BIT_MSB_PAL :
568 pBIH->cBitCount == 4 ? BMP_FORMAT_4BIT_MSN_PAL :
569 pBIH->cBitCount == 8 ? BMP_FORMAT_8BIT_PAL :
570 pBIH->cBitCount == 16 ? BMP_FORMAT_16BIT_TC_LSB_MASK :
571 pBIH->cBitCount == 24 ? BMP_FORMAT_24BIT_TC_BGR :
572 pBIH->cBitCount == 32 ? BMP_FORMAT_32BIT_TC_MASK : 0UL );
574 if( BMP_SCANLINE_FORMAT( pBuffer->mnFormat ) )
576 pBuffer->mnWidth = maSize.Width();
577 pBuffer->mnHeight = maSize.Height();
578 pBuffer->mnScanlineSize = AlignedWidth4Bytes( maSize.Width() * pBIH->cBitCount );
579 pBuffer->mnBitCount = (USHORT) pBIH->cBitCount;
581 if( pBuffer->mnBitCount <= 8 )
583 const USHORT nPalCount = ImplGetDIBColorCount( mhDIB );
585 pBuffer->maPalette.SetEntryCount( nPalCount );
587 if( nPalCount )
588 memcpy( pBuffer->maPalette.ImplGetColorBuffer(), pBI->argbColor, nPalCount * sizeof( RGB2 ) );
590 pBuffer->mpBits = (BYTE*) pBI + *(ULONG*) pBI + nPalCount * sizeof( RGB2 );
592 else
593 pBuffer->mpBits = (BYTE*) pBI + *(ULONG*) pBI;
595 else
597 delete pBuffer;
598 pBuffer = NULL;
603 if( pBuffer && mhDIB1Subst )
605 rtl_freeMemory( (void*)mhDIB1Subst );
606 mhDIB1Subst = 0;
609 return pBuffer;
612 // ------------------------------------------------------------------
614 void Os2SalBitmap::ReleaseBuffer( BitmapBuffer* pBuffer, bool bReadOnly )
616 if( pBuffer )
618 if( mhDIB )
620 if( !bReadOnly && !!pBuffer->maPalette )
622 // bitmap infos can be found at the beginning of the memory
623 PBITMAPINFO2 pBI = (PBITMAPINFO2) mhDIB;
624 const USHORT nCount = pBuffer->maPalette.GetEntryCount();
626 if( nCount )
627 memcpy( pBI->argbColor, pBuffer->maPalette.ImplGetColorBuffer(), nCount * sizeof( RGB2 ) );
631 delete pBuffer;
635 // ------------------------------------------------------------------
637 void Os2SalBitmap::ImplDecodeRLEBuffer( const BYTE* pSrcBuf, BYTE* pDstBuf,
638 const Size& rSizePixel, BOOL bRLE4 )
640 HPBYTE pRLE = (HPBYTE) pSrcBuf;
641 HPBYTE pDIB = (HPBYTE) pDstBuf;
642 HPBYTE pRow = (HPBYTE) pDstBuf;
643 ULONG nWidthAl = AlignedWidth4Bytes( rSizePixel.Width() * ( bRLE4 ? 4UL : 8UL ) );
644 HPBYTE pLast = pDIB + rSizePixel.Height() * nWidthAl - 1;
645 ULONG nCountByte;
646 ULONG nRunByte;
647 ULONG nX = 0;
648 ULONG i;
649 BYTE cTmp;
650 BOOL bEndDecoding = FALSE;
652 if( pRLE && pDIB )
656 if( !( nCountByte = *pRLE++ ) )
658 nRunByte = *pRLE++;
660 if( nRunByte > 2UL )
662 if( bRLE4 )
664 nCountByte = nRunByte >> 1UL;
666 for( i = 0; i < nCountByte; i++ )
668 cTmp = *pRLE++;
669 ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
670 ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
673 if( nRunByte & 1 )
674 ImplSetPixel4( pDIB, nX++, *pRLE++ >> 4 );
676 if( ( ( nRunByte + 1 ) >> 1 ) & 1 )
677 pRLE++;
679 else
681 memcpy( &pDIB[ nX ], pRLE, nRunByte );
682 pRLE += nRunByte;
683 nX += nRunByte;
685 if( nRunByte & 1 )
686 pRLE++;
689 else if( !nRunByte )
691 pDIB = ( pRow += nWidthAl );
692 nX = 0UL;
694 else if( nRunByte == 1 )
695 bEndDecoding = TRUE;
696 else
698 nX += *pRLE++;
699 pDIB = ( pRow += ( *pRLE++ ) * nWidthAl );
702 else
704 cTmp = *pRLE++;
706 if( bRLE4 )
708 nRunByte = nCountByte >> 1;
710 for( i = 0; i < nRunByte; i++ )
712 ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
713 ImplSetPixel4( pDIB, nX++, cTmp & 0x0f );
716 if( nCountByte & 1 )
717 ImplSetPixel4( pDIB, nX++, cTmp >> 4 );
719 else
721 for( i = 0; i < nCountByte; i++ )
722 pDIB[ nX++ ] = cTmp;
726 while( !bEndDecoding && ( pDIB <= pLast ) );
730 bool Os2SalBitmap::GetSystemData( BitmapSystemData& rData )
732 bool bRet = false;
733 if( mhDIB || mhDDB )
735 bRet = true;
736 rData.pDIB = (void*)mhDIB;
737 rData.pDDB = (void*)mhDDB;
739 return bRet;