1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: bmp.cxx,v $
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 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_dtrans.hxx"
40 #include <X11_selection.hxx>
43 using namespace com::sun::star::uno
;
44 using namespace com::sun::star::script
;
45 using namespace com::sun::star::awt
;
52 inline void writeLE( sal_uInt16 nNumber
, sal_uInt8
* pBuffer
)
54 pBuffer
[ 0 ] = (nNumber
& 0xff);
55 pBuffer
[ 1 ] = ((nNumber
>>8)&0xff);
58 inline void writeLE( sal_uInt32 nNumber
, sal_uInt8
* pBuffer
)
60 pBuffer
[ 0 ] = (nNumber
& 0xff);
61 pBuffer
[ 1 ] = ((nNumber
>>8)&0xff);
62 pBuffer
[ 2 ] = ((nNumber
>>16)&0xff);
63 pBuffer
[ 3 ] = ((nNumber
>>24)&0xff);
66 inline sal_uInt16
readLE16( const sal_uInt8
* pBuffer
)
68 return (((sal_uInt16
)pBuffer
[1]) << 8 ) | pBuffer
[0];
71 inline sal_uInt16
readLE32( const sal_uInt8
* pBuffer
)
74 (((sal_uInt32
)pBuffer
[3]) << 24 ) |
75 (((sal_uInt32
)pBuffer
[2]) << 16 ) |
76 (((sal_uInt32
)pBuffer
[1]) << 8 ) |
85 BmpTransporter::BmpTransporter( const Sequence
<sal_Int8
>& rBmp
) :
88 const sal_uInt8
* pData
= (const sal_uInt8
*)rBmp
.getConstArray();
90 if( pData
[0] == 'B' || pData
[1] == 'M' )
93 m_aSize
.Width
= readLE32( pData
+4 );
94 m_aSize
.Height
= readLE32( pData
+8 );
97 m_aSize
.Width
= m_aSize
.Height
= 0;
100 BmpTransporter::~BmpTransporter()
104 com::sun::star::awt::Size SAL_CALL
BmpTransporter::getSize() throw()
109 Sequence
< sal_Int8
> SAL_CALL
BmpTransporter::getDIB() throw()
114 Sequence
< sal_Int8
> SAL_CALL
BmpTransporter::getMaskDIB() throw()
116 return Sequence
< sal_Int8
>();
123 inline void X11_writeScanlinePixel( unsigned long nColor
, sal_uInt8
* pScanline
, int depth
, int x
)
128 pScanline
[ x
/8 ] &= ~(1 << (x
&7));
129 pScanline
[ x
/8 ] |= ((nColor
& 1) << (x
&7));
132 pScanline
[ x
/2 ] &= ((x
&1) ? 0x0f : 0xf0);
133 pScanline
[ x
/2 ] |= ((x
&1) ? (nColor
& 0x0f) : ((nColor
& 0x0f) << 4));
137 pScanline
[ x
] = (nColor
& 0xff);
142 static sal_uInt8
* X11_getPaletteBmpFromImage(
149 sal_uInt32 nColors
= 0;
153 sal_uInt8
* pBuffer
= 0;
154 sal_uInt32 nHeaderSize
, nScanlineSize
;
155 sal_uInt16 nBitCount
;
156 // determine header and scanline size
157 switch( pImage
->depth
)
161 nScanlineSize
= (pImage
->width
+31)/32;
166 nScanlineSize
= (pImage
->width
+1)/2;
172 nScanlineSize
= pImage
->width
;
176 // adjust scan lines to begin on %4 boundaries
177 if( nScanlineSize
& 3 )
179 nScanlineSize
&= 0xfffffffc;
183 // allocate buffer to hold header and scanlines, initialize to zero
184 rOutSize
= nHeaderSize
+ nScanlineSize
*pImage
->height
;
185 pBuffer
= (sal_uInt8
*)rtl_allocateZeroMemory( rOutSize
);
186 for( int y
= 0; y
< pImage
->height
; y
++ )
188 sal_uInt8
* pScanline
= pBuffer
+ nHeaderSize
+ (pImage
->height
-1-y
)*nScanlineSize
;
189 for( int x
= 0; x
< pImage
->width
; x
++ )
191 unsigned long nPixel
= XGetPixel( pImage
, x
, y
);
192 if( nPixel
>= nColors
)
194 X11_writeScanlinePixel( nPixel
, pScanline
, pImage
->depth
, x
);
198 // fill in header fields
202 writeLE( nHeaderSize
, pBuffer
+10 );
203 writeLE( (sal_uInt32
)40, pBuffer
+14 );
204 writeLE( (sal_uInt32
)pImage
->width
, pBuffer
+18 );
205 writeLE( (sal_uInt32
)pImage
->height
, pBuffer
+22 );
206 writeLE( (sal_uInt16
)1, pBuffer
+26 );
207 writeLE( nBitCount
, pBuffer
+28 );
208 writeLE( (sal_uInt32
)(DisplayWidth(pDisplay
,DefaultScreen(pDisplay
))*1000/DisplayWidthMM(pDisplay
,DefaultScreen(pDisplay
))), pBuffer
+38);
209 writeLE( (sal_uInt32
)(DisplayHeight(pDisplay
,DefaultScreen(pDisplay
))*1000/DisplayHeightMM(pDisplay
,DefaultScreen(pDisplay
))), pBuffer
+42);
210 writeLE( nColors
, pBuffer
+46 );
211 writeLE( nColors
, pBuffer
+50 );
214 if( nColors
> (1U << nBitCount
) ) // paranoia
215 nColors
= (1U << nBitCount
);
216 for( unsigned long nPixel
= 0; nPixel
< nColors
; nPixel
++ )
218 aColors
[nPixel
].flags
= DoRed
| DoGreen
| DoBlue
;
219 aColors
[nPixel
].pixel
= nPixel
;
221 XQueryColors( pDisplay
, aColormap
, aColors
, nColors
);
222 for( sal_uInt32 i
= 0; i
< nColors
; i
++ )
224 pBuffer
[ 54 + i
*4 ] = (sal_uInt8
)(aColors
[i
].blue
>> 8);
225 pBuffer
[ 55 + i
*4 ] = (sal_uInt8
)(aColors
[i
].green
>> 8);
226 pBuffer
[ 56 + i
*4 ] = (sal_uInt8
)(aColors
[i
].red
>> 8);
234 inline unsigned long doRightShift( unsigned long nValue
, int nShift
)
236 return (nShift
> 0) ? (nValue
>> nShift
) : (nValue
<< (-nShift
));
239 inline unsigned long doLeftShift( unsigned long nValue
, int nShift
)
241 return (nShift
> 0) ? (nValue
<< nShift
) : (nValue
>> (-nShift
));
244 static void getShift( unsigned long nMask
, int& rShift
, int& rSigBits
, int& rShift2
)
246 unsigned long nUseMask
= nMask
;
248 while( nMask
& 0xffffff00 )
254 while( ! (nMask
& 0x00000080) )
260 int nRotate
= sizeof(unsigned long)*8 - rShift
;
262 nMask
= doRightShift( nUseMask
, rShift
) ;
272 rShift2
= 8-rSigBits
;
275 static sal_uInt8
* X11_getTCBmpFromImage(
282 // get masks from visual info (guesswork)
284 if( ! XMatchVisualInfo( pDisplay
, nScreenNo
, pImage
->depth
, TrueColor
, &aVInfo
) )
289 sal_uInt8
* pBuffer
= 0;
290 sal_uInt32 nHeaderSize
= 60;
291 sal_uInt32 nScanlineSize
= pImage
->width
*3;
293 // adjust scan lines to begin on %4 boundaries
294 if( nScanlineSize
& 3 )
296 nScanlineSize
&= 0xfffffffc;
299 int nRedShift
, nRedSig
, nRedShift2
= 0;
300 getShift( aVInfo
.red_mask
, nRedShift
, nRedSig
, nRedShift2
);
301 int nGreenShift
, nGreenSig
, nGreenShift2
= 0;
302 getShift( aVInfo
.green_mask
, nGreenShift
, nGreenSig
, nGreenShift2
);
303 int nBlueShift
, nBlueSig
, nBlueShift2
= 0;
304 getShift( aVInfo
.blue_mask
, nBlueShift
, nBlueSig
, nBlueShift2
);
306 // allocate buffer to hold header and scanlines, initialize to zero
307 rOutSize
= nHeaderSize
+ nScanlineSize
*pImage
->height
;
308 pBuffer
= (sal_uInt8
*)rtl_allocateZeroMemory( rOutSize
);
309 for( int y
= 0; y
< pImage
->height
; y
++ )
311 sal_uInt8
* pScanline
= pBuffer
+ nHeaderSize
+ (pImage
->height
-1-y
)*nScanlineSize
;
312 for( int x
= 0; x
< pImage
->width
; x
++ )
314 unsigned long nPixel
= XGetPixel( pImage
, x
, y
);
316 sal_uInt8 nValue
= (sal_uInt8
)doRightShift( nPixel
&aVInfo
.blue_mask
, nBlueShift
);
318 nValue
|= (nValue
>> nBlueShift2
);
319 *pScanline
++ = nValue
;
321 nValue
= (sal_uInt8
)doRightShift( nPixel
&aVInfo
.green_mask
, nGreenShift
);
323 nValue
|= (nValue
>> nGreenShift2
);
324 *pScanline
++ = nValue
;
326 nValue
= (sal_uInt8
)doRightShift( nPixel
&aVInfo
.red_mask
, nRedShift
);
328 nValue
|= (nValue
>> nRedShift2
);
329 *pScanline
++ = nValue
;
333 // fill in header fields
337 writeLE( nHeaderSize
, pBuffer
+10 );
338 writeLE( (sal_uInt32
)40, pBuffer
+14 );
339 writeLE( (sal_uInt32
)pImage
->width
, pBuffer
+18 );
340 writeLE( (sal_uInt32
)pImage
->height
, pBuffer
+22 );
341 writeLE( (sal_uInt16
)1, pBuffer
+26 );
342 writeLE( (sal_uInt16
)24, pBuffer
+28 );
343 writeLE( (sal_uInt32
)(DisplayWidth(pDisplay
,DefaultScreen(pDisplay
))*1000/DisplayWidthMM(pDisplay
,DefaultScreen(pDisplay
))), pBuffer
+38);
344 writeLE( (sal_uInt32
)(DisplayHeight(pDisplay
,DefaultScreen(pDisplay
))*1000/DisplayHeightMM(pDisplay
,DefaultScreen(pDisplay
))), pBuffer
+42);
351 sal_uInt8
* x11::X11_getBmpFromPixmap(
358 // get geometry of drawable
361 unsigned int w
, h
, bw
, d
;
362 XGetGeometry( pDisplay
, aDrawable
, &aRoot
, &x
, &y
, &w
, &h
, &bw
, &d
);
364 // find which screen we are on
365 int nScreenNo
= ScreenCount( pDisplay
);
368 if( RootWindow( pDisplay
, nScreenNo
) == aRoot
)
374 if( aColormap
== None
)
375 aColormap
= DefaultColormap( pDisplay
, nScreenNo
);
378 XImage
* pImage
= XGetImage( pDisplay
, aDrawable
, 0, 0, w
, h
, AllPlanes
, ZPixmap
);
382 sal_uInt8
* pBmp
= d
<= 8 ?
383 X11_getPaletteBmpFromImage( pDisplay
, pImage
, aColormap
, rOutSize
) :
384 X11_getTCBmpFromImage( pDisplay
, pImage
, rOutSize
, nScreenNo
);
385 XDestroyImage( pImage
);
390 void x11::X11_freeBmp( sal_uInt8
* pBmp
)
392 rtl_freeMemory( pBmp
);
399 PixmapHolder::PixmapHolder( Display
* pDisplay
) :
400 m_pDisplay( pDisplay
),
405 /* try to get a 24 bit true color visual, if that fails,
406 * revert to default visual
408 if( ! XMatchVisualInfo( m_pDisplay
, DefaultScreen( m_pDisplay
), 24, TrueColor
, &m_aInfo
) )
410 #if OSL_DEBUG_LEVEL > 1
411 fprintf( stderr
, "PixmapHolder reverting to default visual\n" );
413 Visual
* pVisual
= DefaultVisual( m_pDisplay
, DefaultScreen( m_pDisplay
) );
414 m_aInfo
.screen
= DefaultScreen( m_pDisplay
);
415 m_aInfo
.visual
= pVisual
;
416 m_aInfo
.visualid
= pVisual
->visualid
;
417 m_aInfo
.c_class
= pVisual
->c_class
;
418 m_aInfo
.red_mask
= pVisual
->red_mask
;
419 m_aInfo
.green_mask
= pVisual
->green_mask
;
420 m_aInfo
.blue_mask
= pVisual
->blue_mask
;
421 m_aInfo
.depth
= DefaultDepth( m_pDisplay
, m_aInfo
.screen
);
423 m_aColormap
= DefaultColormap( m_pDisplay
, m_aInfo
.screen
);
424 #if OSL_DEBUG_LEVEL > 1
425 static const char* pClasses
[] =
426 { "StaticGray", "GrayScale", "StaticColor", "PseudoColor", "TrueColor", "DirectColor" };
427 fprintf( stderr
, "PixmapHolder visual: id = 0x%lx, class = %s (%d), depth=%d; color map = 0x%lx\n",
429 (m_aInfo
.c_class
>= 0 && unsigned(m_aInfo
.c_class
) < sizeof(pClasses
)/sizeof(pClasses
[0])) ? pClasses
[m_aInfo
.c_class
] : "<unknown>",
434 if( m_aInfo
.c_class
== TrueColor
)
436 int nRedSig
, nGreenSig
, nBlueSig
;
437 m_nRedShift
= m_nRedShift2
= 0;
438 getShift( m_aInfo
.red_mask
, m_nRedShift
, nRedSig
, m_nRedShift2
);
439 m_nGreenShift
= m_nGreenShift2
= 0;
440 getShift( m_aInfo
.green_mask
, m_nGreenShift
, nGreenSig
, m_nGreenShift2
);
441 m_nBlueShift
= m_nBlueShift2
= 0;
442 getShift( m_aInfo
.blue_mask
, m_nBlueShift
, nBlueSig
, m_nBlueShift2
);
444 m_nBlueShift2Mask
= m_nBlueShift2
? ~((unsigned long)((1<<m_nBlueShift2
)-1)) : ~0L;
445 m_nGreenShift2Mask
= m_nGreenShift2
? ~((unsigned long)((1<<m_nGreenShift2
)-1)) : ~0L;
446 m_nRedShift2Mask
= m_nRedShift2
? ~((unsigned long)((1<<m_nRedShift2
)-1)) : ~0L;
450 PixmapHolder::~PixmapHolder()
452 if( m_aPixmap
!= None
)
453 XFreePixmap( m_pDisplay
, m_aPixmap
);
454 if( m_aBitmap
!= None
)
455 XFreePixmap( m_pDisplay
, m_aBitmap
);
458 unsigned long PixmapHolder::getTCPixel( sal_uInt8 r
, sal_uInt8 g
, sal_uInt8 b
) const
460 unsigned long nPixel
= 0;
461 unsigned long nValue
= (unsigned long)b
;
462 nValue
&= m_nBlueShift2Mask
;
463 nPixel
|= doLeftShift( nValue
, m_nBlueShift
);
465 nValue
= (unsigned long)g
;
466 nValue
&= m_nGreenShift2Mask
;
467 nPixel
|= doLeftShift( nValue
, m_nGreenShift
);
469 nValue
= (unsigned long)r
;
470 nValue
&= m_nRedShift2Mask
;
471 nPixel
|= doLeftShift( nValue
, m_nRedShift
);
476 void PixmapHolder::setBitmapDataPalette( const sal_uInt8
* pData
, XImage
* pImage
)
479 XColor aPalette
[256];
481 sal_uInt32 nColors
= readLE32( pData
+32 );
482 sal_uInt32 nWidth
= readLE32( pData
+4 );
483 sal_uInt32 nHeight
= readLE32( pData
+8 );
484 sal_uInt16 nDepth
= readLE16( pData
+14 );
486 for( sal_uInt16 i
= 0 ; i
< nColors
; i
++ )
488 if( m_aInfo
.c_class
!= TrueColor
)
490 aPalette
[i
].red
= ((unsigned short)pData
[42 + i
*4]) << 8 | ((unsigned short)pData
[42 + i
*4]);
491 aPalette
[i
].green
= ((unsigned short)pData
[41 + i
*4]) << 8 | ((unsigned short)pData
[41 + i
*4]);
492 aPalette
[i
].blue
= ((unsigned short)pData
[40 + i
*4]) << 8 | ((unsigned short)pData
[40 + i
*4]);
493 XAllocColor( m_pDisplay
, m_aColormap
, aPalette
+i
);
496 aPalette
[i
].pixel
= getTCPixel( pData
[42+i
*4], pData
[41+i
*4], pData
[40+i
*4] );
498 const sal_uInt8
* pBMData
= pData
+ readLE32( pData
) + 4*nColors
;
500 sal_uInt32 nScanlineSize
= 0;
504 nScanlineSize
= (nWidth
+31)/32;
507 nScanlineSize
= (nWidth
+1)/2;
510 nScanlineSize
= nWidth
;
513 // adjust scan lines to begin on %4 boundaries
514 if( nScanlineSize
& 3 )
516 nScanlineSize
&= 0xfffffffc;
520 // allocate buffer to hold header and scanlines, initialize to zero
521 for( unsigned int y
= 0; y
< nHeight
; y
++ )
523 const sal_uInt8
* pScanline
= pBMData
+ (nHeight
-1-y
)*nScanlineSize
;
524 for( unsigned int x
= 0; x
< nWidth
; x
++ )
529 case 1: nCol
= (pScanline
[ x
/8 ] & (0x80 >> (x
&7))) != 0 ? 0 : 1; break;
532 nCol
= (int)(pScanline
[ x
/2 ] >> 4);
534 nCol
= (int)(pScanline
[ x
/2 ] & 0x0f);
536 case 8: nCol
= (int)pScanline
[x
];
538 XPutPixel( pImage
, x
, y
, aPalette
[nCol
].pixel
);
543 void PixmapHolder::setBitmapDataTCDither( const sal_uInt8
* pData
, XImage
* pImage
)
545 XColor aPalette
[216];
549 for( int r
= 0; r
< 6; r
++ )
551 for( int g
= 0; g
< 6; g
++ )
553 for( int b
= 0; b
< 6; b
++ )
556 aPalette
[i
].red
= r
== 5 ? 0xffff : r
*10922;
557 aPalette
[i
].green
= g
== 5 ? 0xffff : g
*10922;
558 aPalette
[i
].blue
= b
== 5 ? 0xffff : b
*10922;
559 aPalette
[i
].pixel
= 0;
560 if( ! XAllocColor( m_pDisplay
, m_aColormap
, aPalette
+i
) )
568 XColor aRealPalette
[256];
569 int nColors
= 1 << m_aInfo
.depth
;
571 for( i
= 0; i
< nColors
; i
++ )
572 aRealPalette
[i
].pixel
= (unsigned long)i
;
573 XQueryColors( m_pDisplay
, m_aColormap
, aRealPalette
, nColors
);
574 for( i
= 0; i
< nColors
; i
++ )
577 36*(sal_uInt8
)(aRealPalette
[i
].red
/10923) +
578 6*(sal_uInt8
)(aRealPalette
[i
].green
/10923) +
579 (sal_uInt8
)(aRealPalette
[i
].blue
/10923);
580 if( aPalette
[nIndex
].pixel
== 0 )
581 aPalette
[nIndex
] = aRealPalette
[i
];
585 sal_uInt32 nWidth
= readLE32( pData
+4 );
586 sal_uInt32 nHeight
= readLE32( pData
+8 );
588 const sal_uInt8
* pBMData
= pData
+ readLE32( pData
);
589 sal_uInt32 nScanlineSize
= nWidth
*3;
590 // adjust scan lines to begin on %4 boundaries
591 if( nScanlineSize
& 3 )
593 nScanlineSize
&= 0xfffffffc;
597 for( int y
= 0; y
< (int)nHeight
; y
++ )
599 const sal_uInt8
* pScanline
= pBMData
+ (nHeight
-1-(sal_uInt32
)y
)*nScanlineSize
;
600 for( int x
= 0; x
< (int)nWidth
; x
++ )
602 sal_uInt8 b
= pScanline
[3*x
];
603 sal_uInt8 g
= pScanline
[3*x
+1];
604 sal_uInt8 r
= pScanline
[3*x
+2];
605 sal_uInt8 i
= 36*(r
/43) + 6*(g
/43) + (b
/43);
607 XPutPixel( pImage
, x
, y
, aPalette
[ i
].pixel
);
612 void PixmapHolder::setBitmapDataTC( const sal_uInt8
* pData
, XImage
* pImage
)
614 sal_uInt32 nWidth
= readLE32( pData
+4 );
615 sal_uInt32 nHeight
= readLE32( pData
+8 );
617 const sal_uInt8
* pBMData
= pData
+ readLE32( pData
);
618 sal_uInt32 nScanlineSize
= nWidth
*3;
619 // adjust scan lines to begin on %4 boundaries
620 if( nScanlineSize
& 3 )
622 nScanlineSize
&= 0xfffffffc;
626 for( int y
= 0; y
< (int)nHeight
; y
++ )
628 const sal_uInt8
* pScanline
= pBMData
+ (nHeight
-1-(sal_uInt32
)y
)*nScanlineSize
;
629 for( int x
= 0; x
< (int)nWidth
; x
++ )
631 unsigned long nPixel
= getTCPixel( pScanline
[3*x
+2], pScanline
[3*x
+1], pScanline
[3*x
] );
632 XPutPixel( pImage
, x
, y
, nPixel
);
637 bool PixmapHolder::needsConversion( const sal_uInt8
* pData
)
639 if( pData
[0] != 'B' || pData
[1] != 'M' )
643 sal_uInt32 nDepth
= readLE32( pData
+14 );
646 if( m_aInfo
.c_class
!= TrueColor
)
649 else if( nDepth
!= (sal_uInt32
)m_aInfo
.depth
)
651 if( m_aInfo
.c_class
!= TrueColor
)
658 Pixmap
PixmapHolder::setBitmapData( const sal_uInt8
* pData
)
660 if( pData
[0] != 'B' || pData
[1] != 'M' )
665 // reject compressed data
666 if( readLE32( pData
+ 16 ) != 0 )
669 sal_uInt32 nWidth
= readLE32( pData
+4 );
670 sal_uInt32 nHeight
= readLE32( pData
+8 );
672 if( m_aPixmap
!= None
)
673 XFreePixmap( m_pDisplay
, m_aPixmap
), m_aPixmap
= None
;
674 if( m_aBitmap
!= None
)
675 XFreePixmap( m_pDisplay
, m_aBitmap
), m_aBitmap
= None
;
677 m_aPixmap
= XCreatePixmap( m_pDisplay
,
678 RootWindow( m_pDisplay
, m_aInfo
.screen
),
679 nWidth
, nHeight
, m_aInfo
.depth
);
681 if( m_aPixmap
!= None
)
684 aImage
.width
= (int)nWidth
;
685 aImage
.height
= (int)nHeight
;
687 aImage
.format
= ZPixmap
;
689 aImage
.byte_order
= ImageByteOrder( m_pDisplay
);
690 aImage
.bitmap_unit
= BitmapUnit( m_pDisplay
);
691 aImage
.bitmap_bit_order
= BitmapBitOrder( m_pDisplay
);
692 aImage
.bitmap_pad
= BitmapPad( m_pDisplay
);
693 aImage
.depth
= m_aInfo
.depth
;
694 aImage
.red_mask
= m_aInfo
.red_mask
;
695 aImage
.green_mask
= m_aInfo
.green_mask
;
696 aImage
.blue_mask
= m_aInfo
.blue_mask
;
697 aImage
.bytes_per_line
= 0; // filled in by XInitImage
698 if( m_aInfo
.depth
<= 8 )
699 aImage
.bits_per_pixel
= m_aInfo
.depth
;
701 aImage
.bits_per_pixel
= 8*((m_aInfo
.depth
+7)/8);
702 aImage
.obdata
= NULL
;
704 XInitImage( &aImage
);
705 aImage
.data
= (char*)rtl_allocateMemory( nHeight
*aImage
.bytes_per_line
);
707 if( readLE32( pData
+14 ) == 24 )
709 if( m_aInfo
.c_class
== TrueColor
)
710 setBitmapDataTC( pData
, &aImage
);
712 setBitmapDataTCDither( pData
, &aImage
);
715 setBitmapDataPalette( pData
, &aImage
);
718 XPutImage( m_pDisplay
,
720 DefaultGC( m_pDisplay
, m_aInfo
.screen
),
727 rtl_freeMemory( aImage
.data
);
729 // prepare bitmap (mask)
730 m_aBitmap
= XCreatePixmap( m_pDisplay
,
731 RootWindow( m_pDisplay
, m_aInfo
.screen
),
732 nWidth
, nHeight
, 1 );
734 aVal
.function
= GXcopy
;
735 aVal
.foreground
= 0xffffffff;
736 GC aGC
= XCreateGC( m_pDisplay
, m_aBitmap
, GCFunction
| GCForeground
, &aVal
);
737 XFillRectangle( m_pDisplay
, m_aBitmap
, aGC
, 0, 0, nWidth
, nHeight
);
738 XFreeGC( m_pDisplay
, aGC
);