+unsigned char wxImage::GetRed( int x, int y ) const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ int w = M_IMGDATA->m_width;
+ int h = M_IMGDATA->m_height;
+
+ wxCHECK_MSG( (x>=0) && (y>=0) && (x<w) && (y<h), 0, wxT("invalid image index") );
+
+ long pos = (y * w + x) * 3;
+
+ return M_IMGDATA->m_data[pos];
+}
+
+unsigned char wxImage::GetGreen( int x, int y ) const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ int w = M_IMGDATA->m_width;
+ int h = M_IMGDATA->m_height;
+
+ wxCHECK_MSG( (x>=0) && (y>=0) && (x<w) && (y<h), 0, wxT("invalid image index") );
+
+ long pos = (y * w + x) * 3;
+
+ return M_IMGDATA->m_data[pos+1];
+}
+
+unsigned char wxImage::GetBlue( int x, int y ) const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ int w = M_IMGDATA->m_width;
+ int h = M_IMGDATA->m_height;
+
+ wxCHECK_MSG( (x>=0) && (y>=0) && (x<w) && (y<h), 0, wxT("invalid image index") );
+
+ long pos = (y * w + x) * 3;
+
+ return M_IMGDATA->m_data[pos+2];
+}
+
+bool wxImage::Ok() const
+{
+ // image of 0 width or height can't be considered ok - at least because it
+ // causes crashes in ConvertToBitmap() if we don't catch it in time
+ wxImageRefData *data = M_IMGDATA;
+ return data && data->m_ok && data->m_width && data->m_height;
+}
+
+char unsigned *wxImage::GetData() const
+{
+ wxCHECK_MSG( Ok(), (char unsigned *)NULL, wxT("invalid image") );
+
+ return M_IMGDATA->m_data;
+}
+
+void wxImage::SetData( char unsigned *data )
+{
+ wxCHECK_RET( Ok(), wxT("invalid image") );
+
+ wxImageRefData *newRefData = new wxImageRefData();
+
+ newRefData->m_width = M_IMGDATA->m_width;
+ newRefData->m_height = M_IMGDATA->m_height;
+ newRefData->m_data = data;
+ newRefData->m_ok = TRUE;
+ newRefData->m_maskRed = M_IMGDATA->m_maskRed;
+ newRefData->m_maskGreen = M_IMGDATA->m_maskGreen;
+ newRefData->m_maskBlue = M_IMGDATA->m_maskBlue;
+ newRefData->m_hasMask = M_IMGDATA->m_hasMask;
+
+ UnRef();
+
+ m_refData = newRefData;
+}
+
+void wxImage::SetData( char unsigned *data, int new_width, int new_height )
+{
+ wxImageRefData *newRefData = new wxImageRefData();
+
+ if (m_refData)
+ {
+ newRefData->m_width = new_width;
+ newRefData->m_height = new_height;
+ newRefData->m_data = data;
+ newRefData->m_ok = TRUE;
+ newRefData->m_maskRed = M_IMGDATA->m_maskRed;
+ newRefData->m_maskGreen = M_IMGDATA->m_maskGreen;
+ newRefData->m_maskBlue = M_IMGDATA->m_maskBlue;
+ newRefData->m_hasMask = M_IMGDATA->m_hasMask;
+ }
+ else
+ {
+ newRefData->m_width = new_width;
+ newRefData->m_height = new_height;
+ newRefData->m_data = data;
+ newRefData->m_ok = TRUE;
+ }
+
+ UnRef();
+
+ m_refData = newRefData;
+}
+
+void wxImage::SetMaskColour( unsigned char r, unsigned char g, unsigned char b )
+{
+ wxCHECK_RET( Ok(), wxT("invalid image") );
+
+ M_IMGDATA->m_maskRed = r;
+ M_IMGDATA->m_maskGreen = g;
+ M_IMGDATA->m_maskBlue = b;
+ M_IMGDATA->m_hasMask = TRUE;
+}
+
+unsigned char wxImage::GetMaskRed() const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ return M_IMGDATA->m_maskRed;
+}
+
+unsigned char wxImage::GetMaskGreen() const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ return M_IMGDATA->m_maskGreen;
+}
+
+unsigned char wxImage::GetMaskBlue() const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ return M_IMGDATA->m_maskBlue;
+}
+
+void wxImage::SetMask( bool mask )
+{
+ wxCHECK_RET( Ok(), wxT("invalid image") );
+
+ M_IMGDATA->m_hasMask = mask;
+}
+
+bool wxImage::HasMask() const
+{
+ wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") );
+
+ return M_IMGDATA->m_hasMask;
+}
+
+int wxImage::GetWidth() const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ return M_IMGDATA->m_width;
+}
+
+int wxImage::GetHeight() const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ return M_IMGDATA->m_height;
+}
+
+
+bool wxImage::FindFirstUnusedColour(
+ unsigned char *r, unsigned char *g, unsigned char *b,
+ unsigned char startR, unsigned char startG, unsigned char startB)
+{
+ wxHashTable hTable;
+ unsigned long key;
+
+ ComputeHistogram( hTable );
+
+ unsigned char r2 = startR;
+ unsigned char g2 = startG;
+ unsigned char b2 = startB;
+
+ key = (r2 << 16) | (g2 << 8) | b2;
+
+ while ( (wxHNode *) hTable.Get(key) )
+ {
+ // color already used
+ r2++;
+ if ( r2 >= 255 )
+ {
+ r2 = 0;
+ g2++;
+ if ( g2 >= 255 )
+ {
+ g2 = 0;
+ b2++;
+ if ( b2 >= 255 )
+ {
+ wxLogError( _("GetUnusedColour:: No Unused Color in image ") );
+ return FALSE;
+ }
+ }
+ }
+
+ key = (r2 << 16) | (g2 << 8) | b2;
+ }
+
+ if (r) *r = r2;
+ if (g) *g = g2;
+ if (b) *b = b2;
+
+ return TRUE;
+}
+
+
+bool wxImage::SetMaskFromImage(const wxImage& mask,
+ unsigned char mr, unsigned char mg, unsigned char mb)
+{
+ // check that the images are the same size
+ if ( (M_IMGDATA->m_height != mask.GetHeight() ) || (M_IMGDATA->m_width != mask.GetWidth () ) )
+ {
+ wxLogError( _("Image and Mask have different sizes") );
+ return FALSE;
+ }
+
+ // find unused colour
+ unsigned char r,g,b ;
+ if (!FindFirstUnusedColour(&r, &g, &b))
+ {
+ wxLogError( _("No Unused Color in image being masked") );
+ return FALSE ;
+ }
+
+ char unsigned *imgdata = GetData();
+ char unsigned *maskdata = mask.GetData();
+
+ const int w = GetWidth();
+ const int h = GetHeight();
+
+ for (int j = 0; j < h; j++)
+ {
+ for (int i = 0; i < w; i++)
+ {
+ if ((maskdata[0] == mr) && (maskdata[1] == mg) && (maskdata[2] == mb))
+ {
+ imgdata[0] = r;
+ imgdata[1] = g;
+ imgdata[2] = b;
+ }
+ imgdata += 3;
+ maskdata += 3;
+ }
+ }
+
+ SetMaskColour(r, g, b);
+ SetMask(TRUE);
+
+ return TRUE;
+}
+
+#if wxUSE_PALETTE
+
+// Palette functions
+
+bool wxImage::HasPalette() const
+{
+ if (!Ok())
+ return FALSE;
+
+ return M_IMGDATA->m_palette.Ok();
+}
+
+const wxPalette& wxImage::GetPalette() const