+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
+{
+ wxCHECK_MSG( Ok(), wxNullPalette, wxT("invalid image") );
+
+ return M_IMGDATA->m_palette;
+}
+
+void wxImage::SetPalette(const wxPalette& palette)
+{
+ wxCHECK_RET( Ok(), wxT("invalid image") );
+
+ M_IMGDATA->m_palette = palette;
+}
+
+#endif // wxUSE_PALETTE
+
+// Option functions (arbitrary name/value mapping)
+void wxImage::SetOption(const wxString& name, const wxString& value)
+{
+ wxCHECK_RET( Ok(), wxT("invalid image") );
+
+ int idx = M_IMGDATA->m_optionNames.Index(name, FALSE);
+ if (idx == wxNOT_FOUND)
+ {
+ M_IMGDATA->m_optionNames.Add(name);
+ M_IMGDATA->m_optionValues.Add(value);
+ }
+ else
+ {
+ M_IMGDATA->m_optionNames[idx] = name;
+ M_IMGDATA->m_optionValues[idx] = value;
+ }
+}
+
+void wxImage::SetOption(const wxString& name, int value)
+{
+ wxString valStr;
+ valStr.Printf(wxT("%d"), value);
+ SetOption(name, valStr);
+}
+
+wxString wxImage::GetOption(const wxString& name) const
+{
+ wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid image") );
+
+ int idx = M_IMGDATA->m_optionNames.Index(name, FALSE);
+ if (idx == wxNOT_FOUND)
+ return wxEmptyString;
+ else
+ return M_IMGDATA->m_optionValues[idx];
+}
+
+int wxImage::GetOptionInt(const wxString& name) const
+{
+ wxCHECK_MSG( Ok(), 0, wxT("invalid image") );
+
+ return wxAtoi(GetOption(name));
+}
+
+bool wxImage::HasOption(const wxString& name) const
+{
+ wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") );
+
+ return (M_IMGDATA->m_optionNames.Index(name, FALSE) != wxNOT_FOUND);
+}
+
+bool wxImage::LoadFile( const wxString& filename, long type )
+{
+#if wxUSE_STREAMS
+ if (wxFileExists(filename))
+ {
+ wxFileInputStream stream(filename);
+ wxBufferedInputStream bstream( stream );
+ return LoadFile(bstream, type);
+ }
+ else
+ {
+ wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() );
+
+ return FALSE;
+ }
+#else // !wxUSE_STREAMS
+ return FALSE;
+#endif // wxUSE_STREAMS
+}
+
+bool wxImage::LoadFile( const wxString& filename, const wxString& mimetype )
+{
+#if wxUSE_STREAMS
+ if (wxFileExists(filename))
+ {
+ wxFileInputStream stream(filename);
+ wxBufferedInputStream bstream( stream );
+ return LoadFile(bstream, mimetype);
+ }
+ else
+ {
+ wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() );
+
+ return FALSE;
+ }
+#else // !wxUSE_STREAMS
+ return FALSE;
+#endif // wxUSE_STREAMS
+}
+
+bool wxImage::SaveFile( const wxString& filename, int type )
+{
+#if wxUSE_STREAMS
+ wxFileOutputStream stream(filename);
+
+ if ( stream.LastError() == wxStream_NOERROR )
+ {
+ wxBufferedOutputStream bstream( stream );
+ return SaveFile(bstream, type);
+ }
+#endif // wxUSE_STREAMS
+
+ return FALSE;