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"
27 #include "../png/png.h"
29 #include "wx/filefn.h"
30 #include "wx/wfstream.h"
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 class wxImageRefData
: public wxObjectRefData
46 ~wxImageRefData(void);
50 unsigned char *m_data
;
52 unsigned char m_maskRed
,m_maskGreen
,m_maskBlue
;
56 wxImageRefData::wxImageRefData(void)
60 m_data
= (unsigned char*) NULL
;
68 wxImageRefData::~wxImageRefData(void)
70 if (m_data
) free( m_data
);
73 wxList
wxImage::sm_handlers
;
75 //-----------------------------------------------------------------------------
77 #define M_IMGDATA ((wxImageRefData *)m_refData)
79 #if !USE_SHARED_LIBRARIES
80 IMPLEMENT_DYNAMIC_CLASS(wxImage
, wxObject
)
87 wxImage::wxImage( int width
, int height
)
89 Create( width
, height
);
92 wxImage::wxImage( const wxString
& name
, long type
)
94 LoadFile( name
, type
);
97 wxImage::wxImage( wxInputStream
& stream
, long type
)
99 LoadFile( stream
, type
);
102 wxImage::wxImage( const wxImage
& image
)
107 wxImage::wxImage( const wxImage
* image
)
109 if (image
) Ref(*image
);
112 void wxImage::Create( int width
, int height
)
114 m_refData
= new wxImageRefData();
116 M_IMGDATA
->m_data
= (unsigned char *) malloc( width
*height
*3 );
117 if (M_IMGDATA
->m_data
)
119 for (int l
= 0; l
< width
*height
*3; l
++) M_IMGDATA
->m_data
[l
] = 0;
121 M_IMGDATA
->m_width
= width
;
122 M_IMGDATA
->m_height
= height
;
123 M_IMGDATA
->m_ok
= TRUE
;
131 void wxImage::Destroy()
136 wxImage
wxImage::Scale( int width
, int height
)
140 wxCHECK_MSG( Ok(), image
, "invlaid image" );
142 wxCHECK_MSG( (width
> 0) && (height
> 0), image
, "invalid image size" );
144 image
.Create( width
, height
);
146 char unsigned *data
= image
.GetData();
148 wxCHECK_MSG( data
, image
, "unable to create image" );
150 if (M_IMGDATA
->m_hasMask
)
151 image
.SetMaskColour( M_IMGDATA
->m_maskRed
, M_IMGDATA
->m_maskGreen
, M_IMGDATA
->m_maskBlue
);
153 double xscale
= (double)width
/ (double)M_IMGDATA
->m_width
;
154 double yscale
= (double)height
/ (double)M_IMGDATA
->m_height
;
156 for (int j
= 0; j
< height
; j
++)
158 for (int i
= 0; i
< width
; i
++)
160 int new_pos
= 3*(j
*width
+ i
);
161 int old_pos
= 3*((long)(j
/yscale
)*M_IMGDATA
->m_width
+ (long)(i
/xscale
));
162 data
[ new_pos
] = M_IMGDATA
->m_data
[ old_pos
];
163 data
[ new_pos
+1 ] = M_IMGDATA
->m_data
[ old_pos
+1 ];
164 data
[ new_pos
+2 ] = M_IMGDATA
->m_data
[ old_pos
+2 ];
171 void wxImage::SetRGB( int x
, int y
, unsigned char r
, unsigned char g
, unsigned char b
)
173 wxCHECK_RET( Ok(), "invalid image" );
175 int w
= M_IMGDATA
->m_width
;
176 int h
= M_IMGDATA
->m_height
;
178 wxCHECK_RET( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), "invalid image index" );
180 long pos
= (y
* w
+ x
) * 3;
182 M_IMGDATA
->m_data
[ pos
] = r
;
183 M_IMGDATA
->m_data
[ pos
+1 ] = g
;
184 M_IMGDATA
->m_data
[ pos
+2 ] = b
;
187 unsigned char wxImage::GetRed( int x
, int y
)
189 wxCHECK_MSG( Ok(), 0, "invalid image" );
191 int w
= M_IMGDATA
->m_width
;
192 int h
= M_IMGDATA
->m_height
;
194 wxCHECK_MSG( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), 0, "invalid image index" );
196 long pos
= (y
* w
+ x
) * 3;
198 return M_IMGDATA
->m_data
[pos
];
201 unsigned char wxImage::GetGreen( int x
, int y
)
203 wxCHECK_MSG( Ok(), 0, "invalid image" );
205 int w
= M_IMGDATA
->m_width
;
206 int h
= M_IMGDATA
->m_height
;
208 wxCHECK_MSG( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), 0, "invalid image index" );
210 long pos
= (y
* w
+ x
) * 3;
212 return M_IMGDATA
->m_data
[pos
+1];
215 unsigned char wxImage::GetBlue( int x
, int y
)
217 wxCHECK_MSG( Ok(), 0, "invalid image" );
219 int w
= M_IMGDATA
->m_width
;
220 int h
= M_IMGDATA
->m_height
;
222 wxCHECK_MSG( (x
>=0) && (y
>=0) && (x
<w
) && (y
<h
), 0, "invalid image index" );
224 long pos
= (y
* w
+ x
) * 3;
226 return M_IMGDATA
->m_data
[pos
+2];
229 bool wxImage::Ok() const
231 return (M_IMGDATA
&& M_IMGDATA
->m_ok
);
234 char unsigned *wxImage::GetData() const
236 wxCHECK_MSG( Ok(), (char unsigned *)NULL
, "invalid image" );
238 return M_IMGDATA
->m_data
;
241 void wxImage::SetData( char unsigned *WXUNUSED(data
) )
243 wxCHECK_RET( Ok(), "invalid image" );
246 void wxImage::SetMaskColour( unsigned char r
, unsigned char g
, unsigned char b
)
248 wxCHECK_RET( Ok(), "invalid image" );
250 M_IMGDATA
->m_maskRed
= r
;
251 M_IMGDATA
->m_maskGreen
= g
;
252 M_IMGDATA
->m_maskBlue
= b
;
253 M_IMGDATA
->m_hasMask
= TRUE
;
256 unsigned char wxImage::GetMaskRed() const
258 wxCHECK_MSG( Ok(), 0, "invalid image" );
260 return M_IMGDATA
->m_maskRed
;
263 unsigned char wxImage::GetMaskGreen() const
265 wxCHECK_MSG( Ok(), 0, "invalid image" );
267 return M_IMGDATA
->m_maskGreen
;
270 unsigned char wxImage::GetMaskBlue() const
272 wxCHECK_MSG( Ok(), 0, "invalid image" );
274 return M_IMGDATA
->m_maskBlue
;
277 void wxImage::SetMask( bool mask
)
279 wxCHECK_RET( Ok(), "invalid image" );
281 M_IMGDATA
->m_hasMask
= mask
;
284 bool wxImage::HasMask() const
286 wxCHECK_MSG( Ok(), FALSE
, "invalid image" );
288 return M_IMGDATA
->m_hasMask
;
291 int wxImage::GetWidth() const
293 wxCHECK_MSG( Ok(), 0, "invalid image" );
295 return M_IMGDATA
->m_width
;
298 int wxImage::GetHeight() const
300 wxCHECK_MSG( Ok(), 0, "invalid image" );
302 return M_IMGDATA
->m_height
;
305 bool wxImage::LoadFile( const wxString
& filename
, long type
)
307 if (wxFileExists(filename
))
309 wxFileInputStream
stream(filename
);
310 return LoadFile(stream
, type
);
314 wxLogWarning( "Image file does not exist." );
320 bool wxImage::LoadFile( wxInputStream
& stream
, long type
)
324 m_refData
= new wxImageRefData
;
326 wxImageHandler
*handler
= FindHandler(type
);
330 wxLogWarning( "No image handler for type %d defined.", type
);
335 return handler
->LoadFile( this, stream
);
338 bool wxImage::SaveFile( const wxString
& filename
, int type
)
340 wxFileOutputStream
stream(filename
);
342 if ( stream
.LastError() == wxStream_NOERROR
)
343 return SaveFile(stream
, type
);
348 bool wxImage::SaveFile( wxOutputStream
& stream
, int type
)
350 wxCHECK_MSG( Ok(), FALSE
, "invalid image" );
352 wxImageHandler
*handler
= FindHandler(type
);
356 wxLogWarning( "No image handler for type %d defined.", type
);
361 return handler
->SaveFile( this, stream
);
364 void wxImage::AddHandler( wxImageHandler
*handler
)
366 // make sure that the memory will be freed at the program end
367 sm_handlers
.DeleteContents(TRUE
);
369 sm_handlers
.Append( handler
);
372 void wxImage::InsertHandler( wxImageHandler
*handler
)
374 // make sure that the memory will be freed at the program end
375 sm_handlers
.DeleteContents(TRUE
);
377 sm_handlers
.Insert( handler
);
380 bool wxImage::RemoveHandler( const wxString
& name
)
382 wxImageHandler
*handler
= FindHandler(name
);
385 sm_handlers
.DeleteObject(handler
);
392 wxImageHandler
*wxImage::FindHandler( const wxString
& name
)
394 wxNode
*node
= sm_handlers
.First();
397 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
398 if (handler
->GetName() == name
) return handler
;
401 return (wxImageHandler
*)NULL
;
404 wxImageHandler
*wxImage::FindHandler( const wxString
& extension
, long bitmapType
)
406 wxNode
*node
= sm_handlers
.First();
409 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
410 if ( handler
->GetExtension() == extension
&&
411 (bitmapType
== -1 || handler
->GetType() == bitmapType
) )
415 return (wxImageHandler
*)NULL
;
418 wxImageHandler
*wxImage::FindHandler( long bitmapType
)
420 wxNode
*node
= sm_handlers
.First();
423 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
424 if (handler
->GetType() == bitmapType
) return handler
;
430 void wxImage::InitStandardHandlers()
432 AddHandler( new wxBMPHandler
);
434 AddHandler( new wxPNGHandler
);
438 void wxImage::CleanUpHandlers()
440 wxNode
*node
= sm_handlers
.First();
443 wxImageHandler
*handler
= (wxImageHandler
*)node
->Data();
444 wxNode
*next
= node
->Next();
451 //-----------------------------------------------------------------------------
453 //-----------------------------------------------------------------------------
455 #if !USE_SHARED_LIBRARIES
456 IMPLEMENT_DYNAMIC_CLASS(wxImageHandler
,wxObject
)
459 bool wxImageHandler::LoadFile( wxImage
*WXUNUSED(image
), wxInputStream
& WXUNUSED(stream
) )
464 bool wxImageHandler::SaveFile( wxImage
*WXUNUSED(image
), wxOutputStream
& WXUNUSED(stream
) )
469 //-----------------------------------------------------------------------------
471 //-----------------------------------------------------------------------------
475 #if !USE_SHARED_LIBRARIES
476 IMPLEMENT_DYNAMIC_CLASS(wxPNGHandler
,wxImageHandler
)
480 static void _PNG_stream_reader( png_structp png_ptr
, png_bytep data
, png_size_t length
)
482 ((wxInputStream
*) png_get_io_ptr( png_ptr
)) -> Read(data
, length
);
485 static void _PNG_stream_writer( png_structp png_ptr
, png_bytep data
, png_size_t length
)
487 ((wxOutputStream
*) png_get_io_ptr( png_ptr
)) -> Write(data
, length
);
490 bool wxPNGHandler::LoadFile( wxImage
*image
, wxInputStream
& stream
)
492 // VZ: as this function uses setjmp() the only fool proof error handling
493 // method is to use goto (setjmp is not really C++ dtors friendly...)
495 unsigned char **lines
= (unsigned char **) NULL
;
497 png_infop info_ptr
= (png_infop
) NULL
;
501 png_structp png_ptr
= png_create_read_struct( PNG_LIBPNG_VER_STRING
,
503 (png_error_ptr
) NULL
,
504 (png_error_ptr
) NULL
);
508 info_ptr
= png_create_info_struct( png_ptr
);
512 if (setjmp(png_ptr
->jmpbuf
))
515 if (info_ptr
->color_type
== PNG_COLOR_TYPE_RGB_ALPHA
)
518 png_set_read_fn( png_ptr
, &stream
, _PNG_stream_reader
);
520 png_uint_32 width
,height
;
521 int bit_depth
,color_type
,interlace_type
;
523 png_read_info( png_ptr
, info_ptr
);
524 png_get_IHDR( png_ptr
, info_ptr
, &width
, &height
, &bit_depth
, &color_type
, &interlace_type
, (int*) NULL
, (int*) NULL
);
526 if (color_type
== PNG_COLOR_TYPE_PALETTE
)
527 png_set_expand( png_ptr
);
529 png_set_strip_16( png_ptr
);
530 png_set_packing( png_ptr
);
531 if (png_get_valid( png_ptr
, info_ptr
, PNG_INFO_tRNS
))
532 png_set_expand( png_ptr
);
533 png_set_filler( png_ptr
, 0xff, PNG_FILLER_AFTER
);
535 image
->Create( width
, height
);
540 lines
= (unsigned char **)malloc( height
* sizeof(unsigned char *) );
544 for (i
= 0; i
< height
; i
++)
546 if ((lines
[i
] = (unsigned char *)malloc(width
* (sizeof(unsigned char) * 4))) == NULL
)
548 for ( unsigned int n
= 0; n
< i
; n
++ )
554 // loaded successfully!
557 png_read_image( png_ptr
, lines
);
558 png_destroy_read_struct( &png_ptr
, &info_ptr
, (png_infopp
) NULL
);
559 unsigned char *ptr
= image
->GetData();
560 if ((color_type
== PNG_COLOR_TYPE_GRAY
) ||
561 (color_type
== PNG_COLOR_TYPE_GRAY_ALPHA
))
563 for (unsigned int y
= 0; y
< height
; y
++)
565 unsigned char *ptr2
= lines
[y
];
566 for (unsigned int x
= 0; x
< width
; x
++)
568 unsigned char r
= *ptr2
++;
569 unsigned char a
= *ptr2
++;
588 for (unsigned int y
= 0; y
< height
; y
++)
590 unsigned char *ptr2
= lines
[y
];
591 for (unsigned int x
= 0; x
< width
; x
++)
593 unsigned char r
= *ptr2
++;
594 unsigned char g
= *ptr2
++;
595 unsigned char b
= *ptr2
++;
596 unsigned char a
= *ptr2
++;
606 if ((r
== 255) && (g
== 0) && (b
== 255)) r
= 254;
615 for ( unsigned int j
= 0; j
< height
; j
++ )
621 image
->SetMaskColour( 255, 0, 255 );
625 image
->SetMask( FALSE
);
632 wxLogError(_("Couldn't load a PNG image - probably file is corrupted."));
648 png_destroy_read_struct( &png_ptr
, &info_ptr
, (png_infopp
) NULL
);
652 png_destroy_read_struct( &png_ptr
, (png_infopp
) NULL
, (png_infopp
) NULL
);
658 bool wxPNGHandler::SaveFile( wxImage
*image
, wxOutputStream
& stream
)
661 png_structp png_ptr
= png_create_write_struct( PNG_LIBPNG_VER_STRING
, NULL
, NULL
, NULL
);
667 png_infop info_ptr
= png_create_info_struct(png_ptr
);
668 if (info_ptr
== NULL
)
670 png_destroy_write_struct( &png_ptr
, (png_infopp
)NULL
);
674 if (setjmp(png_ptr
->jmpbuf
))
676 png_destroy_write_struct( &png_ptr
, (png_infopp
)NULL
);
680 png_set_write_fn( png_ptr
, &stream
, _PNG_stream_writer
, NULL
);
682 png_set_IHDR( png_ptr
, info_ptr
, image
->GetWidth(), image
->GetHeight(), 8,
683 PNG_COLOR_TYPE_RGB_ALPHA
, PNG_INTERLACE_NONE
,
684 PNG_COMPRESSION_TYPE_BASE
, PNG_FILTER_TYPE_BASE
);
691 png_set_sBIT( png_ptr
, info_ptr
, &sig_bit
);
692 png_write_info( png_ptr
, info_ptr
);
693 png_set_shift( png_ptr
, &sig_bit
);
694 png_set_packing( png_ptr
);
696 unsigned char *data
= (unsigned char *)malloc( image
->GetWidth()*4 );
699 png_destroy_write_struct( &png_ptr
, (png_infopp
)NULL
);
703 for (int y
= 0; y
< image
->GetHeight(); y
++)
705 unsigned char *ptr
= image
->GetData() + (y
* image
->GetWidth() * 3);
706 for (int x
= 0; x
< image
->GetWidth(); x
++)
708 data
[(x
<< 2) + 0] = *ptr
++;
709 data
[(x
<< 2) + 1] = *ptr
++;
710 data
[(x
<< 2) + 2] = *ptr
++;
711 if ((data
[(x
<< 2) + 0] == image
->GetMaskRed()) &&
712 (data
[(x
<< 2) + 1] == image
->GetMaskGreen()) &&
713 (data
[(x
<< 2) + 2] == image
->GetMaskBlue()))
715 data
[(x
<< 2) + 3] = 0;
719 data
[(x
<< 2) + 3] = 255;
722 png_bytep row_ptr
= data
;
723 png_write_rows( png_ptr
, &row_ptr
, 1 );
727 png_write_end( png_ptr
, info_ptr
);
728 png_destroy_write_struct( &png_ptr
, (png_infopp
)&info_ptr
);
737 //-----------------------------------------------------------------------------
739 //-----------------------------------------------------------------------------
741 #if !USE_SHARED_LIBRARIES
742 IMPLEMENT_DYNAMIC_CLASS(wxBMPHandler
,wxImageHandler
)
745 bool wxBMPHandler::LoadFile( wxImage
*image
, wxInputStream
& stream
)
747 unsigned char *data
, *ptr
;
748 int done
, i
, bpp
, planes
, comp
, ncolors
, line
, column
,
749 linesize
, linepos
, rshift
= 0, gshift
= 0, bshift
= 0;
752 long int dbuf
[4], dword
, rmask
= 0, gmask
= 0, bmask
= 0, offset
,
754 off_t start_offset
= stream
.TellI();
758 unsigned char r
, g
, b
;
768 #define BI_BITFIELDS 3
775 * Reading the bmp header
778 stream
.Read(&bbuf
, 2);
780 stream
.Read(dbuf
, 4 * 4);
785 stream
.Read(dbuf
, 4 * 2);
786 int width
= (int)dbuf
[0];
787 int height
= (int)dbuf
[1];
790 wxLogError( "Image width > 32767 pixels for file\n" );
795 wxLogError( "Image height > 32767 pixels for file\n" );
798 stream
.Read(&word
, 2);
800 stream
.Read(&word
, 2);
802 if (bpp
!= 1 && bpp
!= 4 && bpp
!= 8 && bpp
&& 16 && bpp
!= 24 && bpp
!= 32)
804 wxLogError( "unknown bitdepth in file\n" );
807 stream
.Read(dbuf
, 4 * 4);
809 if (comp
!= BI_RGB
&& comp
!= BI_RLE4
&& comp
!= BI_RLE8
&& comp
!= BI_BITFIELDS
)
811 wxLogError( "unknown encoding in Windows BMP file\n" );
814 stream
.Read(dbuf
, 4 * 2);
815 ncolors
= (int)dbuf
[0];
818 /* some more sanity checks */
819 if (((comp
== BI_RLE4
) && (bpp
!= 4)) || ((comp
== BI_RLE8
) && (bpp
!= 8)) || ((comp
== BI_BITFIELDS
) && (bpp
!= 16 && bpp
!= 32)))
821 wxLogError( "encoding of BMP doesn't match bitdepth\n" );
826 cmap
= (struct _cmap
*)malloc(sizeof(struct _cmap
) * ncolors
);
830 wxLogError( "Cannot allocate RAM for color map in BMP file\n" );
837 image
->Create( width
, height
);
838 ptr
= image
->GetData();
841 wxLogError( "Cannot allocate RAM for RGB data in file\n" );
848 * Reading the palette, if it exists.
850 if (bpp
< 16 && ncolors
!= 0)
852 for (i
= 0; i
< ncolors
; i
++)
854 stream
.Read(bbuf
, 4);
860 else if (bpp
== 16 || bpp
== 32)
862 if (comp
== BI_BITFIELDS
)
866 stream
.Read(dbuf
, 4 * 3);
870 /* find shift amount.. ugly, but i can't think of a better way */
871 for (bit
= 0; bit
< bpp
; bit
++)
873 if (bmask
& (1 << bit
))
875 if (gmask
& (1 << bit
))
877 if (rmask
& (1 << bit
))
902 * Reading the image data
904 stream
.SeekI(start_offset
+ offset
);
907 /* set the whole image to the background color */
908 if (bpp
< 16 && (comp
== BI_RLE4
|| comp
== BI_RLE8
))
910 for (i
= 0; i
< width
* height
; i
++)
920 #define poffset (line * width * 3 + column * 3)
923 * BMPs are stored upside down... hmmmmmmmmmm....
926 linesize
= ((width
* bpp
+ 31) / 32) * 4;
927 for (line
= (height
- 1); line
>= 0; line
--)
930 for (column
= 0; column
< width
;)
937 aByte
= stream
.GetC();
942 for (bit
= 0; bit
< 8; bit
++)
944 index
= ((aByte
& (0x80 >> bit
)) ? 1 : 0);
945 ptr
[poffset
] = cmap
[index
].r
;
946 ptr
[poffset
+ 1] = cmap
[index
].g
;
947 ptr
[poffset
+ 2] = cmap
[index
].b
;
955 wxLogError( "can't deal with 4bit encoded yet.\n");
964 for (nibble
= 0; nibble
< 2; nibble
++)
966 index
= ((aByte
& (0xF0 >> nibble
* 4)) >> (!nibble
* 4));
969 ptr
[poffset
] = cmap
[index
].r
;
970 ptr
[poffset
+ 1] = cmap
[index
].g
;
971 ptr
[poffset
+ 2] = cmap
[index
].b
;
983 aByte
= stream
.GetC();
988 /* column = width; */
997 aByte
= stream
.GetC();
999 linepos
= column
* bpp
/ 8;
1000 aByte
= stream
.GetC();
1005 int absolute
= aByte
;
1007 for (i
= 0; i
< absolute
; i
++)
1010 aByte
= stream
.GetC();
1011 ptr
[poffset
] = cmap
[aByte
].r
;
1012 ptr
[poffset
+ 1] = cmap
[aByte
].g
;
1013 ptr
[poffset
+ 2] = cmap
[aByte
].b
;
1016 if (absolute
& 0x01)
1017 aByte
= stream
.GetC();
1022 for (i
= 0; i
< first
; i
++)
1024 ptr
[poffset
] = cmap
[aByte
].r
;
1025 ptr
[poffset
+ 1] = cmap
[aByte
].g
;
1026 ptr
[poffset
+ 2] = cmap
[aByte
].b
;
1034 ptr
[poffset
] = cmap
[aByte
].r
;
1035 ptr
[poffset
+ 1] = cmap
[aByte
].g
;
1036 ptr
[poffset
+ 2] = cmap
[aByte
].b
;
1044 stream
.Read(&bbuf
, 3);
1046 ptr
[poffset
] = (unsigned char)bbuf
[2];
1047 ptr
[poffset
+ 1] = (unsigned char)bbuf
[1];
1048 ptr
[poffset
+ 2] = (unsigned char)bbuf
[0];
1055 stream
.Read(&word
, 2);
1057 temp
= (word
& rmask
) >> rshift
;
1058 ptr
[poffset
] = temp
;
1059 temp
= (word
& gmask
) >> gshift
;
1060 ptr
[poffset
+ 1] = temp
;
1061 temp
= (word
& bmask
) >> gshift
;
1062 ptr
[poffset
+ 2] = temp
;
1069 stream
.Read(&dword
, 4);
1071 temp
= (dword
& rmask
) >> rshift
;
1072 ptr
[poffset
] = temp
;
1073 temp
= (dword
& gmask
) >> gshift
;
1074 ptr
[poffset
+ 1] = temp
;
1075 temp
= (dword
& bmask
) >> bshift
;
1076 ptr
[poffset
+ 2] = temp
;
1080 while ((linepos
< linesize
) && (comp
!= 1) && (comp
!= 2))
1082 stream
.Read(&aByte
, 1);
1084 if (stream
.LastError() != wxStream_NOERROR
)
1088 if (cmap
) free(cmap
);
1090 image
->SetMask( FALSE
);
1097 wxBitmap
wxImage::ConvertToBitmap() const
1101 wxCHECK_MSG( Ok(), bitmap
, "invalid image" );
1102 int width
= GetWidth();
1103 int height
= GetHeight();
1104 bitmap
.SetWidth( width
);
1105 bitmap
.SetHeight( height
);
1106 bitmap
.SetDepth( wxDisplayDepth() );
1108 int headersize
= sizeof(BITMAPINFOHEADER
);
1109 LPBITMAPINFO lpDIBh
= (BITMAPINFO
*) malloc( headersize
);
1110 wxCHECK_MSG( lpDIBh
, bitmap
, "could not allocate memory for DIB header" );
1112 // Fill in the DIB header
1113 lpDIBh
->bmiHeader
.biSize
= headersize
;
1114 lpDIBh
->bmiHeader
.biWidth
= width
;
1115 lpDIBh
->bmiHeader
.biHeight
= -height
;
1116 lpDIBh
->bmiHeader
.biSizeImage
= width
* height
* 3;
1118 lpDIBh
->bmiHeader
.biPlanes
= 1;
1119 lpDIBh
->bmiHeader
.biBitCount
= 24;
1120 lpDIBh
->bmiHeader
.biCompression
= BI_RGB
;
1121 lpDIBh
->bmiHeader
.biClrUsed
= 0;
1123 // These seem not needed for our purpose here.
1124 // lpDIBh->bmiHeader.biClrImportant = 0;
1125 // lpDIBh->bmiHeader.biXPelsPerMeter = 0;
1126 // lpDIBh->bmiHeader.biYPelsPerMeter = 0;
1128 unsigned char *lpBits
= (unsigned char *) malloc( width
*height
*3 );
1131 wxFAIL_MSG( "could not allocate memory for DIB" );
1136 unsigned char *data
= GetData();
1138 unsigned char *ptdata
= data
, *ptbits
= lpBits
;
1139 for( int i
=0; i
<width
*height
; i
++ )
1141 *(ptbits
++) = *(ptdata
+2);
1142 *(ptbits
++) = *(ptdata
+1);
1143 *(ptbits
++) = *(ptdata
);
1147 HDC hdc
= ::GetDC(NULL
);
1150 hbitmap
= CreateDIBitmap( hdc
, &(lpDIBh
->bmiHeader
), CBM_INIT
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1152 // The above line is equivalent to the following two lines.
1153 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
1154 // ::SetDIBits( hdc, hbitmap, 0, height, lpBits, lpDIBh, DIB_RGB_COLORS);
1155 // or the following lines
1156 // hbitmap = ::CreateCompatibleBitmap( hdc, width, height );
1157 // HDC memdc = ::CreateCompatibleDC( hdc );
1158 // ::SelectObject( memdc, hbitmap);
1159 // ::SetDIBitsToDevice( memdc, 0, 0, width, height,
1160 // 0, 0, 0, height, (void *)lpBits, lpDIBh, DIB_RGB_COLORS);
1161 // ::SelectObject( memdc, 0 );
1162 // ::DeleteDC( memdc );
1164 bitmap
.SetHBITMAP( (WXHBITMAP
) hbitmap
);
1168 unsigned char r
= GetMaskRed();
1169 unsigned char g
= GetMaskGreen();
1170 unsigned char b
= GetMaskBlue();
1171 unsigned char zero
= 0, one
= 255;
1174 for( int i
=0; i
<width
*height
; i
++ )
1176 if( (*(ptdata
++)!=r
) | (*(ptdata
++)!=g
) | (*(ptdata
++)!=b
) )
1189 hbitmap
= ::CreateBitmap( (WORD
)width
, (WORD
)height
, 1, 1, NULL
);
1190 ::SetDIBits( hdc
, hbitmap
, 0, (WORD
)height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1191 wxMask
*mask
= new wxMask();
1192 mask
->SetMaskBitmap( (WXHBITMAP
) hbitmap
);
1193 bitmap
.SetMask( mask
);
1195 /* The following can also be used but is slow to run
1196 wxColour colour( GetMaskRed(), GetMaskGreen(), GetMaskBlue());
1197 wxMask *mask = new wxMask( bitmap, colour );
1198 bitmap.SetMask( mask );
1202 ::ReleaseDC(NULL
, hdc
);
1206 if( bitmap
.GetHBITMAP() )
1207 bitmap
.SetOk( TRUE
);
1209 bitmap
.SetOk( FALSE
);
1215 wxImage::wxImage( const wxBitmap
&bitmap
)
1219 wxFAIL_MSG( "invalid bitmap" );
1223 int width
= bitmap
.GetWidth();
1224 int height
= bitmap
.GetHeight();
1225 Create( width
, height
);
1226 unsigned char *data
= GetData();
1229 wxFAIL_MSG( "could not allocate data for image" );
1233 int headersize
= sizeof(BITMAPINFOHEADER
);
1234 LPBITMAPINFO lpDIBh
= (BITMAPINFO
*) malloc( headersize
);
1237 wxFAIL_MSG( "could not allocate data for DIB header" );
1242 // Fill in the DIB header
1243 lpDIBh
->bmiHeader
.biSize
= headersize
;
1244 lpDIBh
->bmiHeader
.biWidth
= width
;
1245 lpDIBh
->bmiHeader
.biHeight
= -height
;
1246 lpDIBh
->bmiHeader
.biSizeImage
= width
* height
* 3;
1248 lpDIBh
->bmiHeader
.biPlanes
= 1;
1249 lpDIBh
->bmiHeader
.biBitCount
= 24;
1250 lpDIBh
->bmiHeader
.biCompression
= BI_RGB
;
1251 lpDIBh
->bmiHeader
.biClrUsed
= 0;
1253 // These seem not needed for our purpose here.
1254 // lpDIBh->bmiHeader.biClrImportant = 0;
1255 // lpDIBh->bmiHeader.biXPelsPerMeter = 0;
1256 // lpDIBh->bmiHeader.biYPelsPerMeter = 0;
1258 unsigned char *lpBits
= (unsigned char *) malloc( width
*height
*3 );
1261 wxFAIL_MSG( "could not allocate data for DIB" );
1268 hbitmap
= (HBITMAP
) bitmap
.GetHBITMAP();
1269 HDC hdc
= ::GetDC(NULL
);
1270 ::GetDIBits( hdc
, hbitmap
, 0, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1272 unsigned char *ptdata
= data
, *ptbits
= lpBits
;
1273 for( int i
=0; i
<width
*height
; i
++ )
1275 *(ptdata
++) = *(ptbits
+2);
1276 *(ptdata
++) = *(ptbits
+1);
1277 *(ptdata
++) = *(ptbits
);
1281 if( bitmap
.GetMask() && bitmap
.GetMask()->GetMaskBitmap() )
1283 hbitmap
= (HBITMAP
) bitmap
.GetMask()->GetMaskBitmap();
1284 HDC memdc
= ::CreateCompatibleDC( hdc
);
1285 ::SetTextColor( memdc
, RGB( 0, 0, 0 ) );
1286 ::SetBkColor( memdc
, RGB( 255, 255, 255 ) );
1287 ::GetDIBits( memdc
, hbitmap
, 0, height
, lpBits
, lpDIBh
, DIB_RGB_COLORS
);
1288 ::DeleteDC( memdc
);
1289 unsigned char r
=16, g
=16, b
=16; // background set to RGB(16,16,16)
1292 for( int i
=0; i
<width
*height
; i
++ )
1302 SetMaskColour( r
, g
, b
);
1305 ::ReleaseDC(NULL
, hdc
);
1314 #include "gtk/gtk.h"
1315 #include "gdk/gdk.h"
1316 #include "gdk/gdkx.h"
1318 wxBitmap
wxImage::ConvertToBitmap() const
1322 wxCHECK_MSG( Ok(), bitmap
, "invalid image" );
1324 int width
= GetWidth();
1325 int height
= GetHeight();
1327 bitmap
.SetHeight( height
);
1328 bitmap
.SetWidth( width
);
1332 GdkImage
*data_image
=
1333 gdk_image_new( GDK_IMAGE_FASTEST
, gdk_visual_get_system(), width
, height
);
1335 bitmap
.SetPixmap( gdk_pixmap_new( (GdkWindow
*)&gdk_root_parent
, width
, height
, -1 ) );
1339 GdkImage
*mask_image
= (GdkImage
*) NULL
;
1343 unsigned char *mask_data
= (unsigned char*)malloc( ((width
>> 3)+8) * height
);
1345 mask_image
= gdk_image_new_bitmap( gdk_visual_get_system(), mask_data
, width
, height
);
1347 wxMask
*mask
= new wxMask();
1348 mask
->m_bitmap
= gdk_pixmap_new( (GdkWindow
*)&gdk_root_parent
, width
, height
, 1 );
1350 bitmap
.SetMask( mask
);
1355 GdkVisual
*visual
= gdk_window_get_visual( bitmap
.GetPixmap() );
1356 if (visual
== NULL
) visual
= gdk_window_get_visual( (GdkWindow
*) &gdk_root_parent
);
1357 int bpp
= visual
->depth
;
1359 bitmap
.SetDepth( bpp
);
1361 if ((bpp
== 16) && (visual
->red_mask
!= 0xf800)) bpp
= 15;
1362 if (bpp
< 8) bpp
= 8;
1366 enum byte_order
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR
};
1367 byte_order b_o
= RGB
;
1371 GdkVisual
*visual
= gdk_visual_get_system();
1372 if ((visual
->red_mask
> visual
->green_mask
) && (visual
->green_mask
> visual
->blue_mask
)) b_o
= RGB
;
1373 else if ((visual
->red_mask
> visual
->blue_mask
) && (visual
->blue_mask
> visual
->green_mask
)) b_o
= RGB
;
1374 else if ((visual
->blue_mask
> visual
->red_mask
) && (visual
->red_mask
> visual
->green_mask
)) b_o
= BRG
;
1375 else if ((visual
->blue_mask
> visual
->green_mask
) && (visual
->green_mask
> visual
->red_mask
)) b_o
= BGR
;
1376 else if ((visual
->green_mask
> visual
->red_mask
) && (visual
->red_mask
> visual
->blue_mask
)) b_o
= GRB
;
1377 else if ((visual
->green_mask
> visual
->blue_mask
) && (visual
->blue_mask
> visual
->red_mask
)) b_o
= GBR
;
1380 int r_mask
= GetMaskRed();
1381 int g_mask
= GetMaskGreen();
1382 int b_mask
= GetMaskBlue();
1384 unsigned char* data
= GetData();
1387 for (int y
= 0; y
< height
; y
++)
1389 for (int x
= 0; x
< width
; x
++)
1391 int r
= data
[index
];
1393 int g
= data
[index
];
1395 int b
= data
[index
];
1400 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
1401 gdk_image_put_pixel( mask_image
, x
, y
, 1 );
1403 gdk_image_put_pixel( mask_image
, x
, y
, 0 );
1408 if ((r
== r_mask
) && (b
== b_mask
) && (g
== g_mask
))
1409 gdk_image_put_pixel( mask_image
, x
, y
, 1 );
1411 gdk_image_put_pixel( mask_image
, x
, y
, 0 );
1419 if (wxTheApp
->m_colorCube
)
1421 pixel
= wxTheApp
->m_colorCube
[ ((r
& 0xf8) << 7) + ((g
& 0xf8) << 2) + ((b
& 0xf8) >> 3) ];
1425 GdkColormap
*cmap
= gtk_widget_get_default_colormap();
1426 GdkColor
*colors
= cmap
->colors
;
1427 int max
= 3 * (65536);
1429 for (int i
= 0; i
< cmap
->size
; i
++)
1431 int rdiff
= (r
<< 8) - colors
[i
].red
;
1432 int gdiff
= (g
<< 8) - colors
[i
].green
;
1433 int bdiff
= (b
<< 8) - colors
[i
].blue
;
1434 int sum
= ABS (rdiff
) + ABS (gdiff
) + ABS (bdiff
);
1435 if (sum
< max
) { pixel
= i
; max
= sum
; }
1439 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1445 guint32 pixel
= ((r
& 0xf8) << 7) | ((g
& 0xf8) << 2) | ((b
& 0xf8) >> 3);
1446 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1451 guint32 pixel
= ((r
& 0xf8) << 8) | ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3);
1452 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1461 case RGB
: pixel
= (r
<< 16) | (g
<< 8) | b
; break;
1462 case RBG
: pixel
= (r
<< 16) | (b
<< 8) | g
; break;
1463 case BRG
: pixel
= (b
<< 16) | (r
<< 8) | g
; break;
1464 case BGR
: pixel
= (b
<< 16) | (g
<< 8) | r
; break;
1465 case GRB
: pixel
= (g
<< 16) | (r
<< 8) | b
; break;
1466 case GBR
: pixel
= (g
<< 16) | (b
<< 8) | r
; break;
1468 gdk_image_put_pixel( data_image
, x
, y
, pixel
);
1477 GdkGC
*data_gc
= gdk_gc_new( bitmap
.GetPixmap() );
1479 gdk_draw_image( bitmap
.GetPixmap(), data_gc
, data_image
, 0, 0, 0, 0, width
, height
);
1481 gdk_image_destroy( data_image
);
1482 gdk_gc_unref( data_gc
);
1488 GdkGC
*mask_gc
= gdk_gc_new( bitmap
.GetMask()->GetBitmap() );
1490 gdk_draw_image( bitmap
.GetMask()->GetBitmap(), mask_gc
, mask_image
, 0, 0, 0, 0, width
, height
);
1492 gdk_image_destroy( mask_image
);
1493 gdk_gc_unref( mask_gc
);
1499 wxImage::wxImage( const wxBitmap
&bitmap
)
1501 wxCHECK_RET( bitmap
.Ok(), "invalid bitmap" );
1503 GdkImage
*gdk_image
= gdk_image_get( bitmap
.GetPixmap(),
1505 bitmap
.GetWidth(), bitmap
.GetHeight() );
1507 wxCHECK_RET( gdk_image
, "couldn't create image" );
1509 Create( bitmap
.GetWidth(), bitmap
.GetHeight() );
1510 char unsigned *data
= GetData();
1514 gdk_image_destroy( gdk_image
);
1515 wxFAIL_MSG( "couldn't create image" );
1519 GdkImage
*gdk_image_mask
= (GdkImage
*) NULL
;
1520 if (bitmap
.GetMask())
1522 gdk_image_mask
= gdk_image_get( bitmap
.GetMask()->GetBitmap(),
1524 bitmap
.GetWidth(), bitmap
.GetHeight() );
1526 SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
1529 GdkVisual
*visual
= gdk_window_get_visual( bitmap
.GetPixmap() );
1530 if (visual
== NULL
) visual
= gdk_window_get_visual( (GdkWindow
*) &gdk_root_parent
);
1531 int bpp
= visual
->depth
;
1532 if ((bpp
== 16) && (visual
->red_mask
!= 0xf800)) bpp
= 15;
1534 GdkColormap
*cmap
= gtk_widget_get_default_colormap();
1537 for (int j
= 0; j
< bitmap
.GetHeight(); j
++)
1539 for (int i
= 0; i
< bitmap
.GetWidth(); i
++)
1541 int pixel
= gdk_image_get_pixel( gdk_image
, i
, j
);
1544 data
[pos
] = cmap
->colors
[pixel
].red
>> 8;
1545 data
[pos
+1] = cmap
->colors
[pixel
].green
>> 8;
1546 data
[pos
+2] = cmap
->colors
[pixel
].blue
>> 8;
1547 } else if (bpp
== 15)
1549 data
[pos
] = (pixel
>> 7) & 0xf8;
1550 data
[pos
+1] = (pixel
>> 2) & 0xf8;
1551 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1552 } else if (bpp
== 16)
1554 data
[pos
] = (pixel
>> 8) & 0xf8;
1555 data
[pos
+1] = (pixel
>> 3) & 0xfc;
1556 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1559 data
[pos
] = (pixel
>> 16) & 0xff;
1560 data
[pos
+1] = (pixel
>> 8) & 0xff;
1561 data
[pos
+2] = pixel
& 0xff;
1566 int mask_pixel
= gdk_image_get_pixel( gdk_image_mask
, i
, j
);
1567 if (mask_pixel
== 0)
1579 gdk_image_destroy( gdk_image
);
1580 if (gdk_image_mask
) gdk_image_destroy( gdk_image_mask
);
1590 #include "wx/utils.h"
1593 wxBitmap
wxImage::ConvertToBitmap() const
1597 wxCHECK_MSG( Ok(), bitmap
, "invalid image" );
1599 int width
= GetWidth();
1600 int height
= GetHeight();
1602 bitmap
.SetHeight( height
);
1603 bitmap
.SetWidth( width
);
1605 Display
*dpy
= (Display
*) wxGetDisplay();
1606 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
1607 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
1611 XImage
*data_image
= XCreateImage( dpy
, vis
, bpp
, ZPixmap
, 0, 0, width
, height
, 32, 0 );
1612 data_image
->data
= new char[ data_image
->bytes_per_line
* data_image
->height
];
1614 bitmap
.Create( width
, height
, bpp
);
1619 GdkImage *mask_image = (GdkImage*) NULL;
1623 unsigned char *mask_data = (unsigned char*)malloc( ((width >> 3)+8) * height );
1625 mask_image = gdk_image_new_bitmap( gdk_visual_get_system(), mask_data, width, height );
1627 wxMask *mask = new wxMask();
1628 mask->m_bitmap = gdk_pixmap_new( (GdkWindow*)&gdk_root_parent, width, height, 1 );
1630 bitmap.SetMask( mask );
1634 // Retrieve depth info
1636 XVisualInfo vinfo_template
;
1639 vinfo_template
.visual
= vis
;
1640 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
1641 vinfo_template
.depth
= bpp
;
1644 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
1648 printf("no visual.\n" );
1649 return wxNullBitmap
;
1654 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
1655 if (bpp
< 8) bpp
= 8;
1659 enum byte_order
{ RGB
, RBG
, BRG
, BGR
, GRB
, GBR
};
1660 byte_order b_o
= RGB
;
1664 if ((vi
->red_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->blue_mask
)) b_o
= RGB
;
1665 else if ((vi
->red_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->green_mask
)) b_o
= RGB
;
1666 else if ((vi
->blue_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->green_mask
)) b_o
= BRG
;
1667 else if ((vi
->blue_mask
> vi
->green_mask
) && (vi
->green_mask
> vi
->red_mask
)) b_o
= BGR
;
1668 else if ((vi
->green_mask
> vi
->red_mask
) && (vi
->red_mask
> vi
->blue_mask
)) b_o
= GRB
;
1669 else if ((vi
->green_mask
> vi
->blue_mask
) && (vi
->blue_mask
> vi
->red_mask
)) b_o
= GBR
;
1673 int r_mask = GetMaskRed();
1674 int g_mask = GetMaskGreen();
1675 int b_mask = GetMaskBlue();
1681 Colormap cmap
= (Colormap
) wxTheApp
->GetMainColormap( dpy
);
1683 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
1684 XQueryColors( dpy
, cmap
, colors
, 256 );
1687 unsigned char* data
= GetData();
1690 for (int y
= 0; y
< height
; y
++)
1692 for (int x
= 0; x
< width
; x
++)
1694 int r
= data
[index
];
1696 int g
= data
[index
];
1698 int b
= data
[index
];
1704 if ((r == r_mask) && (b == b_mask) && (g == g_mask))
1705 gdk_image_put_pixel( mask_image, x, y, 1 );
1707 gdk_image_put_pixel( mask_image, x, y, 0 );
1717 if (wxTheApp->m_colorCube)
1719 pixel = wxTheApp->m_colorCube
1720 [ ((r & 0xf8) << 7) + ((g & 0xf8) << 2) + ((b & 0xf8) >> 3) ];
1725 int max
= 3 * (65536);
1726 for (int i
= 0; i
< 256; i
++)
1728 int rdiff
= (r
<< 8) - colors
[i
].red
;
1729 int gdiff
= (g
<< 8) - colors
[i
].green
;
1730 int bdiff
= (b
<< 8) - colors
[i
].blue
;
1731 int sum
= abs (rdiff
) + abs (gdiff
) + abs (bdiff
);
1732 if (sum
< max
) { pixel
= i
; max
= sum
; }
1737 XPutPixel( data_image
, x
, y
, pixel
);
1742 int pixel
= ((r
& 0xf8) << 7) | ((g
& 0xf8) << 2) | ((b
& 0xf8) >> 3);
1743 XPutPixel( data_image
, x
, y
, pixel
);
1748 int pixel
= ((r
& 0xf8) << 8) | ((g
& 0xfc) << 3) | ((b
& 0xf8) >> 3);
1749 XPutPixel( data_image
, x
, y
, pixel
);
1758 case RGB
: pixel
= (r
<< 16) | (g
<< 8) | b
; break;
1759 case RBG
: pixel
= (r
<< 16) | (b
<< 8) | g
; break;
1760 case BRG
: pixel
= (b
<< 16) | (r
<< 8) | g
; break;
1761 case BGR
: pixel
= (b
<< 16) | (g
<< 8) | r
; break;
1762 case GRB
: pixel
= (g
<< 16) | (r
<< 8) | b
; break;
1763 case GBR
: pixel
= (g
<< 16) | (b
<< 8) | r
; break;
1765 XPutPixel( data_image
, x
, y
, pixel
);
1775 gcvalues
.foreground
= BlackPixel( dpy
, DefaultScreen( dpy
) );
1776 GC gc
= XCreateGC( dpy
, RootWindow ( dpy
, DefaultScreen(dpy
) ), GCForeground
, &gcvalues
);
1777 XPutImage( dpy
, (Drawable
)bitmap
.GetPixmap(), gc
, data_image
, 0, 0, 0, 0, width
, height
);
1779 XDestroyImage( data_image
);
1787 GdkGC *mask_gc = gdk_gc_new( bitmap.GetMask()->GetBitmap() );
1789 gdk_draw_image( bitmap.GetMask()->GetBitmap(), mask_gc, mask_image, 0, 0, 0, 0, width, height );
1791 gdk_image_destroy( mask_image );
1792 gdk_gc_unref( mask_gc );
1799 wxImage::wxImage( const wxBitmap
&bitmap
)
1801 wxCHECK_RET( bitmap
.Ok(), "invalid bitmap" );
1803 Display
*dpy
= (Display
*) wxGetDisplay();
1804 Visual
* vis
= DefaultVisual( dpy
, DefaultScreen( dpy
) );
1805 int bpp
= DefaultDepth( dpy
, DefaultScreen( dpy
) );
1807 XImage
*ximage
= XGetImage( dpy
,
1808 (Drawable
)bitmap
.GetPixmap(),
1810 bitmap
.GetWidth(), bitmap
.GetHeight(),
1811 AllPlanes
, ZPixmap
);
1813 wxCHECK_RET( ximage
, "couldn't create image" );
1815 Create( bitmap
.GetWidth(), bitmap
.GetHeight() );
1816 char unsigned *data
= GetData();
1820 XDestroyImage( ximage
);
1821 wxFAIL_MSG( "couldn't create image" );
1826 GdkImage *gdk_image_mask = (GdkImage*) NULL;
1827 if (bitmap.GetMask())
1829 gdk_image_mask = gdk_image_get( bitmap.GetMask()->GetBitmap(),
1831 bitmap.GetWidth(), bitmap.GetHeight() );
1833 SetMaskColour( 16, 16, 16 ); // anything unlikely and dividable
1837 // Retrieve depth info
1839 XVisualInfo vinfo_template
;
1842 vinfo_template
.visual
= vis
;
1843 vinfo_template
.visualid
= XVisualIDFromVisual( vis
);
1844 vinfo_template
.depth
= bpp
;
1847 vi
= XGetVisualInfo( dpy
, VisualIDMask
|VisualDepthMask
, &vinfo_template
, &nitem
);
1851 printf("no visual.\n" );
1855 if ((bpp
== 16) && (vi
->red_mask
!= 0xf800)) bpp
= 15;
1862 Colormap cmap
= (Colormap
)wxTheApp
->GetMainColormap( dpy
);
1864 for (int i
= 0; i
< 256; i
++) colors
[i
].pixel
= i
;
1865 XQueryColors( dpy
, cmap
, colors
, 256 );
1869 for (int j
= 0; j
< bitmap
.GetHeight(); j
++)
1871 for (int i
= 0; i
< bitmap
.GetWidth(); i
++)
1873 int pixel
= XGetPixel( ximage
, i
, j
);
1876 data
[pos
] = colors
[pixel
].red
>> 8;
1877 data
[pos
+1] = colors
[pixel
].green
>> 8;
1878 data
[pos
+2] = colors
[pixel
].blue
>> 8;
1879 } else if (bpp
== 15)
1881 data
[pos
] = (pixel
>> 7) & 0xf8;
1882 data
[pos
+1] = (pixel
>> 2) & 0xf8;
1883 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1884 } else if (bpp
== 16)
1886 data
[pos
] = (pixel
>> 8) & 0xf8;
1887 data
[pos
+1] = (pixel
>> 3) & 0xfc;
1888 data
[pos
+2] = (pixel
<< 3) & 0xf8;
1891 data
[pos
] = (pixel
>> 16) & 0xff;
1892 data
[pos
+1] = (pixel
>> 8) & 0xff;
1893 data
[pos
+2] = pixel
& 0xff;
1899 int mask_pixel = gdk_image_get_pixel( gdk_image_mask, i, j );
1900 if (mask_pixel == 0)
1913 XDestroyImage( ximage
);
1915 if (gdk_image_mask) gdk_image_destroy( gdk_image_mask );