1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "image.h"
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
22 #include "wx/bitmap.h"
26 #include "wx/filefn.h"
27 #include "wx/wfstream.h"
29 #include "wx/module.h"
44 //-----------------------------------------------------------------------------
46 //-----------------------------------------------------------------------------
48 class wxImageRefData
: public wxObjectRefData
53 ~wxImageRefData(void);
57 unsigned char *m_data
;
59 unsigned char m_maskRed
,m_maskGreen
,m_maskBlue
;
63 wxImageRefData::wxImageRefData(void)
67 m_data
= (unsigned char*) NULL
;
75 wxImageRefData::~wxImageRefData(void)
77 if (m_data
) free( m_data
);
80 wxList
wxImage::sm_handlers
;
82 //-----------------------------------------------------------------------------
84 #define M_IMGDATA ((wxImageRefData *)m_refData)
86 #if !USE_SHARED_LIBRARIES
87 IMPLEMENT_DYNAMIC_CLASS(wxImage
, wxObject
)
94 wxImage::wxImage( int width
, int height
)
96 Create( width
, height
);
99 wxImage::wxImage( const wxString
& name
, long type
)
101 LoadFile( name
, type
);
104 wxImage::wxImage( const wxString
& name
, const wxString
& mimetype
)
106 LoadFile( name
, mimetype
);
110 wxImage::wxImage( wxInputStream
& stream
, long type
)
112 LoadFile( stream
, type
);
115 wxImage::wxImage( wxInputStream
& stream
, const wxString
& mimetype
)
117 LoadFile( stream
, mimetype
);
119 #endif // wxUSE_STREAMS
121 wxImage::wxImage( const wxImage
& image
)
126 wxImage::wxImage( const wxImage
* image
)
128 if (image
) Ref(*image
);
131 void wxImage::Create( int width
, int height
)
133 m_refData
= new wxImageRefData();
135 M_IMGDATA
->m_data
= (unsigned char *) malloc( width
*height
*3 );
136 if (M_IMGDATA
->m_data
)
138 for (int l
= 0; l
< width
*height
*3; l
++) M_IMGDATA
->m_data
[l
] = 0;
140 M_IMGDATA
->m_width
= width
;
141 M_IMGDATA
->m_height
= height
;
142 M_IMGDATA
->m_ok
= TRUE
;
150 void wxImage::Destroy()
155 wxImage
wxImage::Scale( int width
, int height
)
159 wxCHECK_MSG( Ok(), image
, _T("invalid image") );
161 wxCHECK_MSG( (width
> 0) && (height
> 0), image
, _T("invalid image size") );
163 image
.Create( width
, height
);
165 char unsigned *data
= image
.GetData();
167 wxCHECK_MSG( data
, image
, _T("unable to create image") );
169 if (M_IMGDATA
->m_hasMask
)
170 image
.SetMaskColour( M_IMGDATA
->m_maskRed
, M_IMGDATA
->m_maskGreen
, M_IMGDATA
->m_maskBlue
);
172 long old_height
= M_IMGDATA
->m_height
;
173 long old_width
= M_IMGDATA
->m_width
;
175 char unsigned *source_data
= M_IMGDATA
->m_data
;
176 char unsigned *target_data
= data
;
178 for (long j
= 0; j
< height
; j
++)
180 long y_offset
= (j
* old_height
/ height
) * old_width
;
182 for (long i
= 0; i
< width
; i
++)
185 source_data
+ 3*(y_offset
+ ((i
* old_width
)/ width
)),
194 void wxImage::SetRGB( int x
, int y
, unsigned char r
, unsigned char g
, unsigned char b
)
196 wxCHECK_RET( Ok(), _T("invalid image") );
198 int w
= M_IMGDATA
->m_width
;
199 int h
= M_IMGDATA
->m_height
;
201 wxCHECK_RET( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), _T("invalid image index") );
203 long pos
= (y
* w
+ x
) * 3;
205 M_IMGDATA
->m_data
[ pos
] = r
;
206 M_IMGDATA
->m_data
[ pos
+1 ] = g
;
207 M_IMGDATA
->m_data
[ pos
+2 ] = b
;
210 unsigned char wxImage::GetRed( int x
, int y
)
212 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
214 int w
= M_IMGDATA
->m_width
;
215 int h
= M_IMGDATA
->m_height
;
217 wxCHECK_MSG( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), 0, _T("invalid image index") );
219 long pos
= (y
* w
+ x
) * 3;
221 return M_IMGDATA
->m_data
[pos
];
224 unsigned char wxImage::GetGreen( int x
, int y
)
226 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
228 int w
= M_IMGDATA
->m_width
;
229 int h
= M_IMGDATA
->m_height
;
231 wxCHECK_MSG( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), 0, _T("invalid image index") );
233 long pos
= (y
* w
+ x
) * 3;
235 return M_IMGDATA
->m_data
[pos
+1];
238 unsigned char wxImage::GetBlue( int x
, int y
)
240 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
242 int w
= M_IMGDATA
->m_width
;
243 int h
= M_IMGDATA
->m_height
;
245 wxCHECK_MSG( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), 0, _T("invalid image index") );
247 long pos
= (y
* w
+ x
) * 3;
249 return M_IMGDATA
->m_data
[pos
+2];
252 bool wxImage::Ok() const
254 return (M_IMGDATA
&& M_IMGDATA
->m_ok
);
257 char unsigned *wxImage::GetData() const
259 wxCHECK_MSG( Ok(), (char unsigned *)NULL
, _T("invalid image") );
261 return M_IMGDATA
->m_data
;
264 void wxImage::SetData( char unsigned *data
)
266 wxCHECK_RET( Ok(), _T("invalid image") );
268 memcpy(M_IMGDATA
->m_data
, data
, M_IMGDATA
->m_width
* M_IMGDATA
->m_height
* 3);
271 void wxImage::SetMaskColour( unsigned char r
, unsigned char g
, unsigned char b
)
273 wxCHECK_RET( Ok(), _T("invalid image") );
275 M_IMGDATA
->m_maskRed
= r
;
276 M_IMGDATA
->m_maskGreen
= g
;
277 M_IMGDATA
->m_maskBlue
= b
;
278 M_IMGDATA
->m_hasMask
= TRUE
;
281 unsigned char wxImage::GetMaskRed() const
283 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
285 return M_IMGDATA
->m_maskRed
;
288 unsigned char wxImage::GetMaskGreen() const
290 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
292 return M_IMGDATA
->m_maskGreen
;
295 unsigned char wxImage::GetMaskBlue() const
297 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
299 return M_IMGDATA
->m_maskBlue
;
302 void wxImage::SetMask( bool mask
)
304 wxCHECK_RET( Ok(), _T("invalid image") );
306 M_IMGDATA
->m_hasMask
= mask
;
309 bool wxImage::HasMask() const
311 wxCHECK_MSG( Ok(), FALSE
, _T("invalid image") );
313 return M_IMGDATA
->m_hasMask
;
316 int wxImage::GetWidth() const
318 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
320 return M_IMGDATA
->m_width
;
323 int wxImage::GetHeight() const
325 wxCHECK_MSG( Ok(), 0, _T("invalid image") );
327 return M_IMGDATA
->m_height
;
330 bool wxImage::LoadFile( const wxString
& filename
, long type
)
333 if (wxFileExists(filename
))
335 wxFileInputStream
stream(filename
);
336 return LoadFile(stream
, type
);
340 wxLogError( _T("Can't load image from file '%s': file does not exist."), filename
.c_str() );
344 #else // !wxUSE_STREAMS
346 #endif // wxUSE_STREAMS
349 bool wxImage::LoadFile( const wxString
& filename
, const wxString
& mimetype
)
352 if (wxFileExists(filename
))
354 wxFileInputStream
stream(filename
);
355 return LoadFile(stream
, mimetype
);
359 wxLogError( _T("Can't load image from file '%s': file does not exist."), filename
.c_str() );
363 #else // !wxUSE_STREAMS
365 #endif // wxUSE_STREAMS
368 bool wxImage::SaveFile( const wxString
& filename
, int type
)
371 wxFileOutputStream
stream(filename
);
373 if ( stream
.LastError() == wxStream_NOERROR
)
374 return SaveFile(stream
, type
);
376 #endif // wxUSE_STREAMS
380 bool wxImage::SaveFile( const wxString
& filename
, const wxString
& mimetype
)
383 wxFileOutputStream
stream(filename
);
385 if ( stream
.LastError() == wxStream_NOERROR
)
386 return SaveFile(stream
, mimetype
);
388 #endif // wxUSE_STREAMS
393 bool wxImage::LoadFile( wxInputStream
& stream
, long type
)
397 m_refData
= new wxImageRefData
;
399 wxImageHandler
*handler
= FindHandler(type
);
403 wxLogWarning( _T("No image handler for type %d defined."), type
);
408 return handler
->LoadFile( this, stream
);
411 bool wxImage::LoadFile( wxInputStream
& stream
, const wxString
& mimetype
)
415 m_refData
= new wxImageRefData
;
417 wxImageHandler
*handler
= FindHandlerMime(mimetype
);
421 wxLogWarning( _T("No image handler for type %s defined."), mimetype
.GetData() );
426 return handler
->LoadFile( this, stream
);
429 bool wxImage::SaveFile( wxOutputStream
& stream
, int type
)
431 wxCHECK_MSG( Ok(), FALSE
, _T("invalid image") );
433 wxImageHandler
*handler
= FindHandler(type
);
437 wxLogWarning( _T("No image handler for type %d defined."), type
);
442 return handler
->SaveFile( this, stream
);
445 bool wxImage::SaveFile( wxOutputStream
& stream
, const wxString
& mimetype
)
447 wxCHECK_MSG( Ok(), FALSE
, _T("invalid image") );
449 wxImageHandler
*handler
= FindHandlerMime(mimetype
);
453 wxLogWarning( _T("No image handler for type %s defined."), mimetype
.GetData() );
458 return handler
->SaveFile( this, stream
);
460 #endif // wxUSE_STREAMS
462 void wxImage::AddHandler( wxImageHandler
*handler
)
464 // make sure that the memory will be freed at the program end
465 sm_handlers
.DeleteContents(TRUE
);
467 sm_handlers
.Append( handler
);
470 void wxImage::InsertHandler( wxImageHandler
*handler
)
472 // make sure that the memory will be freed at the program end
473 sm_handlers
.DeleteContents(TRUE
);
475 sm_handlers
.Insert( handler
);
478 bool wxImage::RemoveHandler( const wxString
& name
)
480 wxImageHandler
*handler
= FindHandler(name
);
483 sm_handlers
.DeleteObject(handler
);
490 wxImageHandler
*wxImage::FindHandler( const wxString
& name
)
492 wxNode
*node
= sm_handlers
.First();
495 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
496 if (handler
->GetName().Cmp(name
) == 0) return handler
;
500 return (wxImageHandler
*)NULL
;
503 wxImageHandler
*wxImage::FindHandler( const wxString
& extension
, long bitmapType
)
505 wxNode
*node
= sm_handlers
.First();
508 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
509 if ( (handler
->GetExtension().Cmp(extension
) == 0) &&
510 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
514 return (wxImageHandler
*)NULL
;
517 wxImageHandler
*wxImage::FindHandler( long bitmapType
)
519 wxNode
*node
= sm_handlers
.First();
522 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
523 if (handler
->GetType() == bitmapType
) return handler
;
529 wxImageHandler
*wxImage::FindHandlerMime( const wxString
& mimetype
)
531 wxNode
*node
= sm_handlers
.First();
534 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
535 if (handler
->GetMimeType().IsSameAs(mimetype
, FALSE
)) return handler
;
541 void wxImage::InitStandardHandlers()
543 AddHandler( new wxBMPHandler
);
546 void wxImage::CleanUpHandlers()
548 wxNode
*node
= sm_handlers
.First();
551 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
552 wxNode
*next
= node
->Next();
559 //-----------------------------------------------------------------------------
561 //-----------------------------------------------------------------------------
563 #if !USE_SHARED_LIBRARIES
564 IMPLEMENT_DYNAMIC_CLASS(wxImageHandler
,wxObject
)
568 bool wxImageHandler::LoadFile( wxImage
*WXUNUSED(image
), wxInputStream
& WXUNUSED(stream
) )
573 bool wxImageHandler::SaveFile( wxImage
*WXUNUSED(image
), wxOutputStream
& WXUNUSED(stream
) )
577 #endif // wxUSE_STREAMS
579 //-----------------------------------------------------------------------------
581 //-----------------------------------------------------------------------------
583 #if !USE_SHARED_LIBRARIES
584 IMPLEMENT_DYNAMIC_CLASS(wxBMPHandler
,wxImageHandler
)
596 #define BI_BITFIELDS 3
599 #define poffset (line * width * 3 + column * 3)
601 bool wxBMPHandler::LoadFile( wxImage
*image
, wxInputStream
& stream
)
603 int rshift
= 0, gshift
= 0, bshift
= 0;
606 wxInt32 dbuf
[4], aDword
,
607 rmask
= 0, gmask
= 0, bmask
= 0;
610 unsigned char r
, g
, b
;
613 off_t start_offset
= stream
.TellI();
618 * Read the BMP header
621 stream
.Read( &bbuf
, 2 );
622 stream
.Read( dbuf
, 4 * 4 );
624 wxInt32 size
= wxINT32_SWAP_FROM_LE( dbuf
[0] );
625 wxInt32 offset
= wxINT32_SWAP_FROM_LE( dbuf
[2] );
627 stream
.Read(dbuf
, 4 * 2);
628 int width
= (int)wxINT32_SWAP_FROM_LE( dbuf
[0] );
629 int height
= (int)wxINT32_SWAP_FROM_LE( dbuf
[1] );
632 wxLogError( _T("Image width > 32767 pixels for file.") );
637 wxLogError( _T("Image height > 32767 pixels for file.") );
641 stream
.Read( &aWord
, 2 );
644 int planes = (int)wxUINT16_SWAP_FROM_LE( aWord );
646 stream
.Read( &aWord
, 2 );
647 int bpp
= (int)wxUINT16_SWAP_FROM_LE( aWord
);
648 if (bpp
!= 1 && bpp
!= 4 && bpp
!= 8 && bpp
!= 16 && bpp
!= 24 && bpp
!= 32)
650 wxLogError( _T("unknown bitdepth in file.") );
654 stream
.Read( dbuf
, 4 * 4 );
655 int comp
= (int)wxINT32_SWAP_FROM_LE( dbuf
[0] );
656 if (comp
!= BI_RGB
&& comp
!= BI_RLE4
&& comp
!= BI_RLE8
&& comp
!= BI_BITFIELDS
)
658 wxLogError( _T("unknown encoding in Windows BMP file.") );
662 stream
.Read( dbuf
, 4 * 2 );
663 int ncolors
= (int)wxINT32_SWAP_FROM_LE( dbuf
[0] );
666 /* some more sanity checks */
667 if (((comp
== BI_RLE4
) && (bpp
!= 4)) ||
668 ((comp
== BI_RLE8
) && (bpp
!= 8)) ||
669 ((comp
== BI_BITFIELDS
) && (bpp
!= 16 && bpp
!= 32)))
671 wxLogError( _T("encoding of BMP doesn't match bitdepth.") );
676 cmap
= (struct _cmap
*)malloc(sizeof(struct _cmap
) * ncolors
);
679 wxLogError( _T("Cannot allocate RAM for color map in BMP file.") );
686 image
->Create( width
, height
);
687 unsigned char *ptr
= image
->GetData();
690 wxLogError( _T("Cannot allocate RAM for RGB data in file.") );
697 * Reading the palette, if it exists.
699 if (bpp
< 16 && ncolors
!= 0)
701 for (int j
= 0; j
< ncolors
; j
++)
703 stream
.Read( bbuf
, 4 );
709 else if (bpp
== 16 || bpp
== 32)
711 if (comp
== BI_BITFIELDS
)
714 stream
.Read( dbuf
, 4 * 3 );
715 bmask
= wxINT32_SWAP_FROM_LE( dbuf
[0] );
716 gmask
= wxINT32_SWAP_FROM_LE( dbuf
[1] );
717 rmask
= wxINT32_SWAP_FROM_LE( dbuf
[2] );
718 /* find shift amount.. ugly, but i can't think of a better way */
719 for (bit
= 0; bit
< bpp
; bit
++)
721 if (bmask
& (1 << bit
))
723 if (gmask
& (1 << bit
))
725 if (rmask
& (1 << bit
))
750 * Reading the image data
752 stream
.SeekI( start_offset
+ offset
);
753 unsigned char *data
= ptr
;
755 /* set the whole image to the background color */
756 if (bpp
< 16 && (comp
== BI_RLE4
|| comp
== BI_RLE8
))
758 for (int i
= 0; i
< width
* height
; i
++)
769 int linesize
= ((width
* bpp
+ 31) / 32) * 4;
771 /* BMPs are stored upside down */
772 for (line
= (height
- 1); line
>= 0; line
--)
775 for (column
= 0; column
< width
;)
781 aByte
= stream
.GetC();
785 for (bit
= 0; bit
< 8; bit
++)
787 index
= ((aByte
& (0x80 >> bit
)) ? 1 : 0);
788 ptr
[poffset
] = cmap
[index
].r
;
789 ptr
[poffset
+ 1] = cmap
[index
].g
;
790 ptr
[poffset
+ 2] = cmap
[index
].b
;
798 wxLogError( _T("Can't deal with 4bit encoded yet.") );
806 for (nibble
= 0; nibble
< 2; nibble
++)
808 index
= ((aByte
& (0xF0 >> nibble
* 4)) >> (!nibble
* 4));
811 ptr
[poffset
] = cmap
[index
].r
;
812 ptr
[poffset
+ 1] = cmap
[index
].g
;
813 ptr
[poffset
+ 2] = cmap
[index
].b
;
824 aByte
= stream
.GetC();
829 /* column = width; */
838 aByte
= stream
.GetC();
840 linepos
= column
* bpp
/ 8;
841 aByte
= stream
.GetC();
846 int absolute
= aByte
;
847 for (int k
= 0; k
< absolute
; k
++)
850 aByte
= stream
.GetC();
851 ptr
[poffset
] = cmap
[aByte
].r
;
852 ptr
[poffset
+ 1] = cmap
[aByte
].g
;
853 ptr
[poffset
+ 2] = cmap
[aByte
].b
;
857 aByte
= stream
.GetC();
862 for (int l
= 0; l
< first
; l
++)
864 ptr
[poffset
] = cmap
[aByte
].r
;
865 ptr
[poffset
+ 1] = cmap
[aByte
].g
;
866 ptr
[poffset
+ 2] = cmap
[aByte
].b
;
874 ptr
[poffset
] = cmap
[aByte
].r
;
875 ptr
[poffset
+ 1] = cmap
[aByte
].g
;
876 ptr
[poffset
+ 2] = cmap
[aByte
].b
;
884 stream
.Read( &bbuf
, 3 );
886 ptr
[poffset
] = (unsigned char)bbuf
[2];
887 ptr
[poffset
+ 1] = (unsigned char)bbuf
[1];
888 ptr
[poffset
+ 2] = (unsigned char)bbuf
[0];
894 stream
.Read( &aWord
, 2 );
895 aWord
= wxUINT16_SWAP_FROM_LE( aWord
);
897 temp
= (aWord
& rmask
) >> rshift
;
899 temp
= (aWord
& gmask
) >> gshift
;
900 ptr
[poffset
+ 1] = temp
;
901 temp
= (aWord
& bmask
) >> gshift
;
902 ptr
[poffset
+ 2] = temp
;
908 stream
.Read( &aDword
, 4 );
909 aDword
= wxINT32_SWAP_FROM_LE( aDword
);
911 temp
= (aDword
& rmask
) >> rshift
;
913 temp
= (aDword
& gmask
) >> gshift
;
914 ptr
[poffset
+ 1] = temp
;
915 temp
= (aDword
& bmask
) >> bshift
;
916 ptr
[poffset
+ 2] = temp
;
920 while ((linepos
< linesize
) && (comp
!= 1) && (comp
!= 2))
922 stream
.Read( &aByte
, 1 );
924 if (stream
.LastError() != wxStream_NOERROR
)
931 image
->SetMask( FALSE
);
935 #endif // wxUSE_STREAMS
939 wxBitmap
wxImage::ConvertToBitmap() const
941 // sizeLimit is the MS upper limit for the DIB size
942 int sizeLimit
= 1024*768*3;
944 // width and height of the device-dependent bitmap
945 int width
= GetWidth();
946 int bmpHeight
= GetHeight();
948 // calc the number of bytes per scanline and padding
949 int bytePerLine
= width
*3;
950 int sizeDWORD
= sizeof( DWORD
);
951 div_t lineBoundary
= div( bytePerLine
, sizeDWORD
);
953 if( lineBoundary
.rem
> 0 )
955 padding
= sizeDWORD
- lineBoundary
.rem
;
956 bytePerLine
+= padding
;
958 // calc the number of DIBs and heights of DIBs
961 int height
= sizeLimit
/bytePerLine
;
962 if( height
>= bmpHeight
)
966 div_t result
= div( bmpHeight
, height
);
967 numDIB
= result
.quot
;
968 hRemain
= result
.rem
;
969 if( hRemain
>0 ) numDIB
++;
972 // set bitmap parameters
974 wxCHECK_MSG( Ok(), bitmap
, _T("invalid image") );
975 bitmap
.SetWidth( width
);
976 bitmap
.SetHeight( bmpHeight
);
977 bitmap
.SetDepth( wxDisplayDepth() );
979 // create a DIB header
980 int headersize
= sizeof(BITMAPINFOHEADER
);
981 LPBITMAPINFO lpDIBh
= (BITMAPINFO
*) malloc( headersize
);
982 wxCHECK_MSG( lpDIBh
, bitmap
, _T("could not allocate memory for DIB header") );
983 // Fill in the DIB header
984 lpDIBh
->bmiHeader
.biSize
= headersize
;
985 lpDIBh
->bmiHeader
.biWidth
= (DWORD
)width
;
986 lpDIBh
->bmiHeader
.biHeight
= (DWORD
)(-height
);
987 lpDIBh
->bmiHeader
.biSizeImage
= bytePerLine
*height
;
988 // the general formula for biSizeImage:
989 // ( ( ( ((DWORD)width*24) +31 ) & ~31 ) >> 3 ) * height;
990 lpDIBh
->bmiHeader
.biPlanes
= 1;
991 lpDIBh
->bmiHeader
.biBitCount
= 24;
992 lpDIBh
->bmiHeader
.biCompression
= BI_RGB
;
993 lpDIBh
->bmiHeader
.biClrUsed
= 0;
994 // These seem not really needed for our purpose here.
995 lpDIBh
->bmiHeader
.biClrImportant
= 0;
996 lpDIBh
->bmiHeader
.biXPelsPerMeter
= 0;
997 lpDIBh
->bmiHeader
.biYPelsPerMeter
= 0;
998 // memory for DIB data
999 unsigned char *lpBits
;
1000 lpBits
= (unsigned char *)malloc( lpDIBh
->bmiHeader
.biSizeImage
);
1003 wxFAIL_MSG( _T("could not allocate memory for DIB") );
1008 // create and set the device-dependent bitmap
1009 HDC hdc
= ::GetDC(NULL
);
1010 HDC memdc
= ::CreateCompatibleDC( hdc
);
1012 hbitmap
= ::CreateCompatibleBitmap( hdc
, width
, bmpHeight
);
1013 ::SelectObject( memdc
, hbitmap
);
1015 // copy image data into DIB data and then into DDB (in a loop)
1016 unsigned char *data
= GetData();
1019 unsigned char *ptdata
= data
;
1020 unsigned char *ptbits
;
1022 for( n
=0; n
<numDIB
; n
++ )
1024 if( numDIB
> 1 && n
== numDIB
-1 && hRemain
> 0 )
1026 // redefine height and size of the (possibly) last smaller DIB
1027 // memory is not reallocated
1029 lpDIBh
->bmiHeader
.biHeight
= (DWORD
)(-height
);
1030 lpDIBh
->bmiHeader
.biSizeImage
= bytePerLine
*height
;
1034 for( j
=0; j
<height
; j
++ )
1036 for( i
=0; i
<width
; i
++ )
1038 *(ptbits
++) = *(ptdata
+2);
1039 *(ptbits
++) = *(ptdata
+1);
1040 *(ptbits
++) = *(ptdata
);
1043 for( i
=0; i
< padding
; i
++ ) *(ptbits
++) = 0;
1045 ::StretchDIBits( memdc
, 0, origin
, width
, height
,\
1046 0, 0, width
, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
, SRCCOPY
);
1048 // if numDIB = 1, lines below can also be used
1049 // hbitmap = CreateDIBitmap( hdc, &(lpDIBh->bmiHeader), CBM_INIT, lpBits, lpDIBh, DIB_RGB_COLORS );
1050 // The above line is equivalent to the following two lines.
1051 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
1052 // ::SetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS);
1053 // or the following lines
1054 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
1055 // HDC memdc = ::CreateCompatibleDC( hdc );
1056 // ::SelectObject( memdc, hbitmap);
1057 // ::SetDIBitsToDevice( memdc, 0, 0, width, height,
1058 // 0, 0, 0, height, (void *)lpBits, lpDIBh, DIB_RGB_COLORS);
1059 // ::SelectObject( memdc, 0 );
1060 // ::DeleteDC( memdc );
1062 bitmap
.SetHBITMAP( (WXHBITMAP
) hbitmap
);
1064 // similarly, created an mono-bitmap for the possible mask
1067 hbitmap
= ::CreateBitmap( (WORD
)width
, (WORD
)bmpHeight
, 1, 1, NULL
);
1068 ::SelectObject( memdc
, hbitmap
);
1069 if( numDIB
== 1 ) height
= bmpHeight
;
1070 else height
= sizeLimit
/bytePerLine
;
1071 lpDIBh
->bmiHeader
.biHeight
= (DWORD
)(-height
);
1072 lpDIBh
->bmiHeader
.biSizeImage
= bytePerLine
*height
;
1074 unsigned char r
= GetMaskRed();
1075 unsigned char g
= GetMaskGreen();
1076 unsigned char b
= GetMaskBlue();
1077 unsigned char zero
= 0, one
= 255;
1079 for( n
=0; n
<numDIB
; n
++ )
1081 if( numDIB
> 1 && n
== numDIB
- 1 && hRemain
> 0 )
1083 // redefine height and size of the (possibly) last smaller DIB
1084 // memory is not reallocated
1086 lpDIBh
->bmiHeader
.biHeight
= (DWORD
)(-height
);
1087 lpDIBh
->bmiHeader
.biSizeImage
= bytePerLine
*height
;
1090 for( int j
=0; j
<height
; j
++ )
1092 for(i
=0; i
<width
; i
++ )
1094 if( (*(ptdata
++)!=r
) | (*(ptdata
++)!=g
) | (*(ptdata
++)!=b
) )
1107 for( i
=0; i
< padding
; i
++ ) *(ptbits
++) = zero
;
1109 ::StretchDIBits( memdc
, 0, origin
, width
, height
,\
1110 0, 0, width
, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
, SRCCOPY
);
1113 // create a wxMask object
1114 wxMask
*mask
= new wxMask();
1115 mask
->SetMaskBitmap( (WXHBITMAP
) hbitmap
);
1116 bitmap
.SetMask( mask
);
1117 // It will be deleted when the wxBitmap object is deleted (as of 01/1999)
1118 /* The following can also be used but is slow to run
1119 wxColour colour( GetMaskRed(), GetMaskGreen(), GetMaskBlue());
1120 wxMask *mask = new wxMask( bitmap, colour );
1121 bitmap.SetMask( mask );
1125 // free allocated resources
1126 ::SelectObject( memdc
, 0 );
1127 ::DeleteDC( memdc
);
1128 ::ReleaseDC(NULL
, hdc
);
1132 // check the wxBitmap object
1133 if( bitmap
.GetHBITMAP() )
1134 bitmap
.SetOk( TRUE
);
1136 bitmap
.SetOk( FALSE
);
1141 wxImage::wxImage( const wxBitmap
&bitmap
)
1146 wxFAIL_MSG( _T("invalid bitmap") );
1150 // create an wxImage object
1151 int width
= bitmap
.GetWidth();
1152 int height
= bitmap
.GetHeight();
1153 Create( width
, height
);
1154 unsigned char *data
= GetData();
1157 wxFAIL_MSG( _T("could not allocate data for image") );
1161 // calc the number of bytes per scanline and padding in the DIB
1162 int bytePerLine
= width
*3;
1163 int sizeDWORD
= sizeof( DWORD
);
1164 div_t lineBoundary
= div( bytePerLine
, sizeDWORD
);
1166 if( lineBoundary
.rem
> 0 )
1168 padding
= sizeDWORD
- lineBoundary
.rem
;
1169 bytePerLine
+= padding
;
1172 // create a DIB header
1173 int headersize
= sizeof(BITMAPINFOHEADER
);
1174 LPBITMAPINFO lpDIBh
= (BITMAPINFO
*) malloc( headersize
);
1177 wxFAIL_MSG( _T("could not allocate data for DIB header") );
1181 // Fill in the DIB header
1182 lpDIBh
->bmiHeader
.biSize
= headersize
;
1183 lpDIBh
->bmiHeader
.biWidth
= width
;
1184 lpDIBh
->bmiHeader
.biHeight
= -height
;
1185 lpDIBh
->bmiHeader
.biSizeImage
= bytePerLine
* height
;
1186 lpDIBh
->bmiHeader
.biPlanes
= 1;
1187 lpDIBh
->bmiHeader
.biBitCount
= 24;
1188 lpDIBh
->bmiHeader
.biCompression
= BI_RGB
;
1189 lpDIBh
->bmiHeader
.biClrUsed
= 0;
1190 // These seem not really needed for our purpose here.
1191 lpDIBh
->bmiHeader
.biClrImportant
= 0;
1192 lpDIBh
->bmiHeader
.biXPelsPerMeter
= 0;
1193 lpDIBh
->bmiHeader
.biYPelsPerMeter
= 0;
1194 // memory for DIB data
1195 unsigned char *lpBits
;
1196 lpBits
= (unsigned char *) malloc( lpDIBh
->bmiHeader
.biSizeImage
);
1199 wxFAIL_MSG( _T("could not allocate data for DIB") );
1205 // copy data from the device-dependent bitmap to the DIB
1206 HDC hdc
= ::GetDC(NULL
);
1208 hbitmap
= (HBITMAP
) bitmap
.GetHBITMAP();
1209 ::GetDIBits( hdc
, hbitmap
, 0, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1211 // copy DIB data into the wxImage object
1213 unsigned char *ptdata
= data
;
1214 unsigned char *ptbits
= lpBits
;
1215 for( i
=0; i
<height
; i
++ )
1217 for( j
=0; j
<width
; j
++ )
1219 *(ptdata
++) = *(ptbits
+2);
1220 *(ptdata
++) = *(ptbits
+1);
1221 *(ptdata
++) = *(ptbits
);
1227 // similarly, set data according to the possible mask bitmap
1228 if( bitmap
.GetMask() && bitmap
.GetMask()->GetMaskBitmap() )
1230 hbitmap
= (HBITMAP
) bitmap
.GetMask()->GetMaskBitmap();
1231 // memory DC created, color set, data copied, and memory DC deleted
1232 HDC memdc
= ::CreateCompatibleDC( hdc
);
1233 ::SetTextColor( memdc
, RGB( 0, 0, 0 ) );
1234 ::SetBkColor( memdc
, RGB( 255, 255, 255 ) );
1235 ::GetDIBits( memdc
, hbitmap
, 0, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1236 ::DeleteDC( memdc
);
1237 // background color set to RGB(16,16,16) in consistent with wxGTK
1238 unsigned char r
=16, g
=16, b
=16;
1241 for( i
=0; i
<height
; i
++ )
1243 for( j
=0; j
<width
; j
++ )
1257 SetMaskColour( r
, g
, b
);
1264 // free allocated resources
1265 ::ReleaseDC(NULL
, hdc
);
1274 #include "gtk/gtk.h"
1275 #include "gdk/gdk.h"
1276 #include "gdk/gdkx.h"
1278 #if (GTK_MINOR_VERSION > 0)
1279 #include "gdk/gdkrgb.h"
1282 wxBitmap
wxImage::ConvertToBitmap() const
1286 wxCHECK_MSG( Ok(), bitmap
, _T("invalid image") );
1288 int width
= GetWidth();
1289 int height
= GetHeight();
1291 bitmap
.SetHeight( height
);
1292 bitmap
.SetWidth( width
);
1294 bitmap
.SetPixmap( gdk_pixmap_new( (GdkWindow
*)&gdk_root_parent
, width
, height
, -1 ) );
1298 GdkVisual
*visual
= gdk_window_get_visual( bitmap
.GetPixmap() );
1299 if (visual
== NULL
) visual
= gdk_window_get_visual( (GdkWindow
*) &gdk_root_parent
);
1300 int bpp
= visual
->depth
;
1302 bitmap
.SetDepth( bpp
);
1304 if ((bpp
== 16) && (visual
->red_mask
!= 0xf800)) bpp
= 15;
1305 if (bpp
< 8) bpp
= 8;
1307 #if (GTK_MINOR_VERSION > 0)
1309 if (!HasMask() && (bpp
> 8))
1311 static bool s_hasInitialized
= FALSE
;
1313 if (!s_hasInitialized
)
1316 s_hasInitialized
= TRUE
;
1319 GdkGC
*gc
= gdk_gc_new( bitmap
.GetPixmap() );
1321 gdk_draw_rgb_image( bitmap
.GetPixmap(),
1325 GDK_RGB_DITHER_NONE
,
1336 // Create picture image
1338 GdkImage
*data_image
=
1339 gdk_image_new( GDK_IMAGE_FASTEST
, gdk_visual_get_system(), width
, height
);
1341 // Create mask image
1343 GdkImage
*mask_image
= (GdkImage
*) NULL
;
1347 unsigned char *mask_data
= (unsigned char*)malloc( ((width
>> 3)+8) * height
);
1349 mask_image
= gdk_image_new_bitmap( gdk_visual_get_system(), mask_data
, width
, height
);
1351 wxMask
*mask
= new wxMask();
1352 mask
->m_bitmap
= gdk_pixmap_new( (GdkWindow
*)&gdk_root_parent
, width
, height
, 1 );
1354 bitmap
.SetMask( mask
);
1359 enum byte_order
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR
};
1360 byte_order b_o
= RGB
;
1364 GdkVisual
*visual
= gdk_visual_get_system();
1365 if ((visual
->red_mask
> visual
->green_mask
) && (visual
->green_mask
> visual
->blue_mask
)) b_o
= RGB
;
1366 else if ((visual
->red_mask
> visual
->blue_mask
) && (visual
->blue_mask
> visual
->green_mask
)) b_o
= RGB
;
1367 else if ((visual
->blue_mask
> visual
->red_mask
) && (visual
->red_mask
> visual
->green_mask
)) b_o
= BRG
;
1368 else if ((visual
->blue_mask
> visual
->green_mask
) && (visual
->green_mask
> visual
->red_mask
)) b_o
= BGR
;
1369 else if ((visual
->green_mask
> visual
->red_mask
) && (visual
->red_mask
> visual
->blue_mask
)) b_o
= GRB
;
1370 else if ((visual
->green_mask
> visual
->blue_mask
) && (visual
->blue_mask
> visual
->red_mask
)) b_o
= GBR
;
1373 int r_mask
= GetMaskRed();
1374 int g_mask
= GetMaskGreen();
1375 int b_mask
= GetMaskBlue();
1377 unsigned char* data
= GetData();
1380 for (int y
= 0; y
< height
; y
++)
1382 for (int x
= 0; x
< width
; x
++)
1384 int r
= data
[index
];
1386 int g
= data
[index
];
1388 int b
= data
[index
];
1393 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
1394 gdk_image_put_pixel( mask_image
, x
, y
, 1 );
1396 gdk_image_put_pixel( mask_image
, x
, y
, 0 );
1401 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
1402 gdk_image_put_pixel( mask_image
, x
, y
, 1 );
1404 gdk_image_put_pixel( mask_image
, x
, y
, 0 );
1412 if (wxTheApp
->m_colorCube
)
1414 pixel
= wxTheApp
->m_colorCube
[ ((r
& 0xf8) << 7) + ((g
& 0xf8) << 2) + ((b
& 0xf8) >> 3) ];
1418 GdkColormap
*cmap
= gtk_widget_get_default_colormap();
1419 GdkColor
*colors
= cmap
->colors
;
1420 int max
= 3 * (65536);
1422 for (int i
= 0; i
< cmap
->size
; i
++)
1424 int rdiff
= (r
<< 8) - colors
[i
].red
;
1425 int gdiff
= (g
<< 8) - colors
[i
].green
;
1426 int bdiff
= (b
<< 8) - colors
[i
].blue
;
1427 int sum
= ABS (rdiff
) + ABS (gdiff
) + ABS (bdiff
);
1428 if (sum
< max
) { pixel
= i
; max
= sum
; }
1432 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1438 guint32 pixel
= ((r
& 0xf8) << 7) | ((g
& 0xf8) << 2) | ((b
& 0xf8) >> 3);
1439 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1444 guint32 pixel
= ((r
& 0xf8) << 8) | ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3);
1445 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1454 case RGB
: pixel
= (r
<< 16) | (g
<< 8) | b
; break;
1455 case RBG
: pixel
= (r
<< 16) | (b
<< 8) | g
; break;
1456 case BRG
: pixel
= (b
<< 16) | (r
<< 8) | g
; break;
1457 case BGR
: pixel
= (b
<< 16) | (g
<< 8) | r
; break;
1458 case GRB
: pixel
= (g
<< 16) | (r
<< 8) | b
; break;
1459 case GBR
: pixel
= (g
<< 16) | (b
<< 8) | r
; break;
1461 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1470 GdkGC
*data_gc
= gdk_gc_new( bitmap
.GetPixmap() );
1472 gdk_draw_image( bitmap
.GetPixmap(), data_gc
, data_image
, 0, 0, 0, 0, width
, height
);
1474 gdk_image_destroy( data_image
);
1475 gdk_gc_unref( data_gc
);
1481 GdkGC
*mask_gc
= gdk_gc_new( bitmap
.GetMask()->GetBitmap() );
1483 gdk_draw_image( bitmap
.GetMask()->GetBitmap(), mask_gc
, mask_image
, 0, 0, 0, 0, width
, height
);
1485 gdk_image_destroy( mask_image
);
1486 gdk_gc_unref( mask_gc
);
1492 wxImage::wxImage( const wxBitmap
&bitmap
)
1494 wxCHECK_RET( bitmap
.Ok(), _T("invalid bitmap") );
1496 GdkImage
*gdk_image
= gdk_image_get( bitmap
.GetPixmap(),
1498 bitmap
.GetWidth(), bitmap
.GetHeight() );
1500 wxCHECK_RET( gdk_image
, _T("couldn't create image") );
1502 Create( bitmap
.GetWidth(), bitmap
.GetHeight() );
1503 char unsigned *data
= GetData();
1507 gdk_image_destroy( gdk_image
);
1508 wxFAIL_MSG( _T("couldn't create image") );
1512 GdkImage
*gdk_image_mask
= (GdkImage
*) NULL
;
1513 if (bitmap
.GetMask())
1515 gdk_image_mask
= gdk_image_get( bitmap
.GetMask()->GetBitmap(),
1517 bitmap
.GetWidth(), bitmap
.GetHeight() );
1519 SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
1522 GdkVisual
*visual
= gdk_window_get_visual( bitmap
.GetPixmap() );
1523 if (visual
== NULL
) visual
= gdk_window_get_visual( (GdkWindow
*) &gdk_root_parent
);
1524 int bpp
= visual
->depth
;
1525 if ((bpp
== 16) && (visual
->red_mask
!= 0xf800)) bpp
= 15;
1527 GdkColormap
*cmap
= gtk_widget_get_default_colormap();
1530 for (int j
= 0; j
< bitmap
.GetHeight(); j
++)
1532 for (int i
= 0; i
< bitmap
.GetWidth(); i
++)
1534 int pixel
= gdk_image_get_pixel( gdk_image
, i
, j
);
1537 data
[pos
] = cmap
->colors
[pixel
].red
>> 8;
1538 data
[pos
+1] = cmap
->colors
[pixel
].green
>> 8;
1539 data
[pos
+2] = cmap
->colors
[pixel
].blue
>> 8;
1540 } else if (bpp
== 15)
1542 data
[pos
] = (pixel
>> 7) & 0xf8;
1543 data
[pos
+1] = (pixel
>> 2) & 0xf8;
1544 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1545 } else if (bpp
== 16)
1547 data
[pos
] = (pixel
>> 8) & 0xf8;
1548 data
[pos
+1] = (pixel
>> 3) & 0xfc;
1549 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1552 data
[pos
] = (pixel
>> 16) & 0xff;
1553 data
[pos
+1] = (pixel
>> 8) & 0xff;
1554 data
[pos
+2] = pixel
& 0xff;
1559 int mask_pixel
= gdk_image_get_pixel( gdk_image_mask
, i
, j
);
1560 if (mask_pixel
== 0)
1572 gdk_image_destroy( gdk_image
);
1573 if (gdk_image_mask
) gdk_image_destroy( gdk_image_mask
);
1581 #include "wx/utils.h"
1584 wxBitmap
wxImage::ConvertToBitmap() const
1588 wxCHECK_MSG( Ok(), bitmap
, _T("invalid image") );
1590 int width
= GetWidth();
1591 int height
= GetHeight();
1593 bitmap
.SetHeight( height
);
1594 bitmap
.SetWidth( width
);
1596 Display
*dpy
= (Display
*) wxGetDisplay();
1597 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
1598 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
1602 XImage
*data_image
= XCreateImage( dpy
, vis
, bpp
, ZPixmap
, 0, 0, width
, height
, 32, 0 );
1603 data_image
->data
= (char*) malloc( data_image
->bytes_per_line
* data_image
->height
);
1605 bitmap
.Create( width
, height
, bpp
);
1610 GdkImage *mask_image = (GdkImage*) NULL;
1614 unsigned char *mask_data = (unsigned char*)malloc( ((width >> 3)+8) * height );
1616 mask_image = gdk_image_new_bitmap( gdk_visual_get_system(), mask_data, width, height );
1618 wxMask *mask = new wxMask();
1619 mask->m_bitmap = gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, 1 );
1621 bitmap.SetMask( mask );
1625 // Retrieve depth info
1627 XVisualInfo vinfo_template
;
1630 vinfo_template
.visual
= vis
;
1631 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
1632 vinfo_template
.depth
= bpp
;
1635 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
1637 wxCHECK_MSG( vi
, wxNullBitmap
, _T("no visual") );
1641 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
1642 if (bpp
< 8) bpp
= 8;
1646 enum byte_order
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR
};
1647 byte_order b_o
= RGB
;
1651 if ((vi
->red_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->blue_mask
)) b_o
= RGB
;
1652 else if ((vi
->red_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->green_mask
)) b_o
= RGB
;
1653 else if ((vi
->blue_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->green_mask
)) b_o
= BRG
;
1654 else if ((vi
->blue_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->red_mask
)) b_o
= BGR
;
1655 else if ((vi
->green_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->blue_mask
)) b_o
= GRB
;
1656 else if ((vi
->green_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->red_mask
)) b_o
= GBR
;
1660 int r_mask = GetMaskRed();
1661 int g_mask = GetMaskGreen();
1662 int b_mask = GetMaskBlue();
1668 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap( dpy
);
1670 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
1671 XQueryColors( dpy
, cmap
, colors
, 256 );
1674 unsigned char* data
= GetData();
1677 for (int y
= 0; y
< height
; y
++)
1679 for (int x
= 0; x
< width
; x
++)
1681 int r
= data
[index
];
1683 int g
= data
[index
];
1685 int b
= data
[index
];
1691 if ((r == r_mask) && (b == b_mask) && (g == g_mask))
1692 gdk_image_put_pixel( mask_image, x, y, 1 );
1694 gdk_image_put_pixel( mask_image, x, y, 0 );
1704 if (wxTheApp->m_colorCube)
1706 pixel = wxTheApp->m_colorCube
1707 [ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
1712 int max
= 3 * (65536);
1713 for (int i
= 0; i
< 256; i
++)
1715 int rdiff
= (r
<< 8) - colors
[i
].red
;
1716 int gdiff
= (g
<< 8) - colors
[i
].green
;
1717 int bdiff
= (b
<< 8) - colors
[i
].blue
;
1718 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
1719 if (sum
< max
) { pixel
= i
; max
= sum
; }
1724 XPutPixel( data_image
, x
, y
, pixel
);
1729 int pixel
= ((r
& 0xf8) << 7) | ((g
& 0xf8) << 2) | ((b
& 0xf8) >> 3);
1730 XPutPixel( data_image
, x
, y
, pixel
);
1735 int pixel
= ((r
& 0xf8) << 8) | ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3);
1736 XPutPixel( data_image
, x
, y
, pixel
);
1745 case RGB
: pixel
= (r
<< 16) | (g
<< 8) | b
; break;
1746 case RBG
: pixel
= (r
<< 16) | (b
<< 8) | g
; break;
1747 case BRG
: pixel
= (b
<< 16) | (r
<< 8) | g
; break;
1748 case BGR
: pixel
= (b
<< 16) | (g
<< 8) | r
; break;
1749 case GRB
: pixel
= (g
<< 16) | (r
<< 8) | b
; break;
1750 case GBR
: pixel
= (g
<< 16) | (b
<< 8) | r
; break;
1752 XPutPixel( data_image
, x
, y
, pixel
);
1762 gcvalues
.foreground
= BlackPixel( dpy
, DefaultScreen( dpy
) );
1763 GC gc
= XCreateGC( dpy
, RootWindow ( dpy
, DefaultScreen(dpy
) ), GCForeground
, &gcvalues
);
1764 XPutImage( dpy
, (Drawable
)bitmap
.GetPixmap(), gc
, data_image
, 0, 0, 0, 0, width
, height
);
1766 XDestroyImage( data_image
);
1774 GdkGC *mask_gc = gdk_gc_new( bitmap.GetMask()->GetBitmap() );
1776 gdk_draw_image( bitmap.GetMask()->GetBitmap(), mask_gc, mask_image, 0, 0, 0, 0, width, height );
1778 gdk_image_destroy( mask_image );
1779 gdk_gc_unref( mask_gc );
1786 wxImage::wxImage( const wxBitmap
&bitmap
)
1788 wxCHECK_RET( bitmap
.Ok(), _T("invalid bitmap") );
1790 Display
*dpy
= (Display
*) wxGetDisplay();
1791 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
1792 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
1794 XImage
*ximage
= XGetImage( dpy
,
1795 (Drawable
)bitmap
.GetPixmap(),
1797 bitmap
.GetWidth(), bitmap
.GetHeight(),
1798 AllPlanes
, ZPixmap
);
1800 wxCHECK_RET( ximage
, _T("couldn't create image") );
1802 Create( bitmap
.GetWidth(), bitmap
.GetHeight() );
1803 char unsigned *data
= GetData();
1807 XDestroyImage( ximage
);
1808 wxFAIL_MSG( _T("couldn't create image") );
1813 GdkImage *gdk_image_mask = (GdkImage*) NULL;
1814 if (bitmap.GetMask())
1816 gdk_image_mask = gdk_image_get( bitmap.GetMask()->GetBitmap(),
1818 bitmap.GetWidth(), bitmap.GetHeight() );
1820 SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
1824 // Retrieve depth info
1826 XVisualInfo vinfo_template
;
1829 vinfo_template
.visual
= vis
;
1830 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
1831 vinfo_template
.depth
= bpp
;
1834 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
1836 wxCHECK_MSG( vi
, wxNullBitmap
, _T("no visual") );
1838 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
1845 Colormap cmap
= (Colormap
)wxTheApp
->GetMainColormap( dpy
);
1847 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
1848 XQueryColors( dpy
, cmap
, colors
, 256 );
1852 for (int j
= 0; j
< bitmap
.GetHeight(); j
++)
1854 for (int i
= 0; i
< bitmap
.GetWidth(); i
++)
1856 int pixel
= XGetPixel( ximage
, i
, j
);
1859 data
[pos
] = colors
[pixel
].red
>> 8;
1860 data
[pos
+1] = colors
[pixel
].green
>> 8;
1861 data
[pos
+2] = colors
[pixel
].blue
>> 8;
1862 } else if (bpp
== 15)
1864 data
[pos
] = (pixel
>> 7) & 0xf8;
1865 data
[pos
+1] = (pixel
>> 2) & 0xf8;
1866 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1867 } else if (bpp
== 16)
1869 data
[pos
] = (pixel
>> 8) & 0xf8;
1870 data
[pos
+1] = (pixel
>> 3) & 0xfc;
1871 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1874 data
[pos
] = (pixel
>> 16) & 0xff;
1875 data
[pos
+1] = (pixel
>> 8) & 0xff;
1876 data
[pos
+2] = pixel
& 0xff;
1882 int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j );
1883 if (mask_pixel == 0)
1896 XDestroyImage( ximage
);
1898 if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );
1903 // A module to allow wxImage initialization/cleanup
1904 // without calling these functions from app.cpp or from
1905 // the user's application.
1907 class wxImageModule
: public wxModule
1909 DECLARE_DYNAMIC_CLASS(wxImageModule
)
1912 bool OnInit() { wxImage::InitStandardHandlers(); return TRUE
; };
1913 void OnExit() { wxImage::CleanUpHandlers(); };
1916 IMPLEMENT_DYNAMIC_CLASS(wxImageModule
, wxModule
)