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 <os2/salgdi.h>
30 #include <os2/saldata.hxx>
31 #include <os2/salbmp.h>
32 #include <vcl/bitmap.hxx> // for BitmapSystemData
33 #include <string.h>
34
35 #ifndef __H_FT2LIB
36 #include <os2/wingdi.h>
37 #include <ft2lib.h>
38 #endif
39
40 // -----------
41 // - Inlines -
42 // -----------
43
ImplSetPixel4(const HPBYTE pScanline,long nX,const PM_BYTE cIndex)44 inline void ImplSetPixel4( const HPBYTE pScanline, long nX, const PM_BYTE cIndex )
45 {
46 PM_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
Os2SalBitmap()56 Os2SalBitmap::Os2SalBitmap() :
57 mhDIB ( 0 ),
58 mhDIB1Subst ( 0 ),
59 mhDDB ( 0 ),
60 mnBitCount ( 0 )
61 {
62 }
63
64 // ------------------------------------------------------------------
65
~Os2SalBitmap()66 Os2SalBitmap::~Os2SalBitmap()
67 {
68 Destroy();
69 }
70
71 // ------------------------------------------------------------------
72
Create(HANDLE hBitmap,bool bDIB,bool bCopyHandle)73 bool Os2SalBitmap::Create( HANDLE hBitmap, bool bDIB, bool bCopyHandle )
74 {
75 sal_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
Create(const Size & rSize,USHORT nBitCount,const BitmapPalette & rPal)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
Create(const SalBitmap & rSSalBitmap)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
Create(const SalBitmap & rSSalBmp,SalGraphics * pSGraphics)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
Create(const SalBitmap & rSSalBmp,USHORT nNewBitCount)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
Destroy()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
ImplReplacehDIB1Subst(HANDLE hDIB1Subst)306 void Os2SalBitmap::ImplReplacehDIB1Subst( HANDLE hDIB1Subst )
307 {
308 if( mhDIB1Subst )
309 rtl_freeMemory( (void*)mhDIB1Subst );
310
311 mhDIB1Subst = hDIB1Subst;
312 }
313
314 // ------------------------------------------------------------------
315
ImplGetDIBColorCount(HANDLE hDIB)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
ImplCreateDIB(const Size & rSize,USHORT nBits,const BitmapPalette & rPal)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
ImplCreateDIB4FromDIB1(HANDLE hDIB1)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 PM_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
ImplCopyDIBOrDDB(HANDLE hHdl,bool bDIB)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 PM_BYTE* pCopy = (PM_BYTE*)rtl_allocateZeroMemory( nSize );
446 memcpy( pCopy, (PM_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
AcquireBuffer(bool bReadOnly)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 PM_BYTE* pOldBits = (PM_BYTE*) pBI + nOffset;
541 PM_BYTE* pNewBits = (PM_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 = (sal_uInt8*) pBI + *(ULONG*) pBI + nPalCount * sizeof( RGB2 );
584 }
585 else
586 pBuffer->mpBits = (sal_uInt8*) 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
ReleaseBuffer(BitmapBuffer * pBuffer,bool bReadOnly)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
ImplDecodeRLEBuffer(const PM_BYTE * pSrcBuf,PM_BYTE * pDstBuf,const Size & rSizePixel,bool bRLE4)630 void Os2SalBitmap::ImplDecodeRLEBuffer( const PM_BYTE* pSrcBuf, PM_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 PM_BYTE cTmp;
643 sal_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
GetSystemData(BitmapSystemData & rData)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