+ imgdata += 3;
+ maskdata += 3;
+ }
+ }
+
+ SetMaskColour(r, g, b);
+ SetMask(true);
+
+ return true;
+}
+
+bool wxImage::ConvertAlphaToMask(unsigned char threshold)
+{
+ if (!HasAlpha())
+ return true;
+
+ unsigned char mr, mg, mb;
+ if (!FindFirstUnusedColour(&mr, &mg, &mb))
+ {
+ wxLogError( _("No unused colour in image being masked.") );
+ return false;
+ }
+
+ AllocExclusive();
+
+ SetMask(true);
+ SetMaskColour(mr, mg, mb);
+
+ unsigned char *imgdata = GetData();
+ unsigned char *alphadata = GetAlpha();
+
+ int w = GetWidth();
+ int h = GetHeight();
+
+ for (int y = 0; y < h; y++)
+ {
+ for (int x = 0; x < w; x++, imgdata += 3, alphadata++)
+ {
+ if (*alphadata < threshold)
+ {
+ imgdata[0] = mr;
+ imgdata[1] = mg;
+ imgdata[2] = mb;
+ }
+ }
+ }
+
+ if( !M_IMGDATA->m_staticAlpha )
+ free(M_IMGDATA->m_alpha);
+
+ M_IMGDATA->m_alpha = NULL;
+ M_IMGDATA->m_staticAlpha = false;
+
+ return true;
+}
+
+// ----------------------------------------------------------------------------
+// Palette functions
+// ----------------------------------------------------------------------------
+
+#if wxUSE_PALETTE
+
+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") );
+
+ AllocExclusive();
+
+ 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") );
+
+ AllocExclusive();
+
+ 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
+{
+ 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);
+}
+
+// ----------------------------------------------------------------------------
+// image I/O
+// ----------------------------------------------------------------------------
+
+bool wxImage::LoadFile( const wxString& WXUNUSED_UNLESS_STREAMS(filename),
+ wxBitmapType WXUNUSED_UNLESS_STREAMS(type),
+ int WXUNUSED_UNLESS_STREAMS(index) )
+{
+#if HAS_FILE_STREAMS
+ if (wxFileExists(filename))
+ {
+ wxImageFileInputStream stream(filename);
+ wxBufferedInputStream bstream( stream );
+ return LoadFile(bstream, type, index);
+ }
+ else
+ {
+ wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() );
+
+ return false;
+ }
+#else // !HAS_FILE_STREAMS
+ return false;
+#endif // HAS_FILE_STREAMS
+}
+
+bool wxImage::LoadFile( const wxString& WXUNUSED_UNLESS_STREAMS(filename),
+ const wxString& WXUNUSED_UNLESS_STREAMS(mimetype),
+ int WXUNUSED_UNLESS_STREAMS(index) )
+{
+#if HAS_FILE_STREAMS
+ if (wxFileExists(filename))
+ {
+ wxImageFileInputStream stream(filename);
+ wxBufferedInputStream bstream( stream );
+ return LoadFile(bstream, mimetype, index);
+ }
+ else
+ {
+ wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() );
+
+ return false;
+ }
+#else // !HAS_FILE_STREAMS
+ return false;
+#endif // HAS_FILE_STREAMS
+}
+
+
+bool wxImage::SaveFile( const wxString& filename ) const
+{
+ wxString ext = filename.AfterLast('.').Lower();
+
+ wxImageHandler *handler = FindHandler(ext, wxBITMAP_TYPE_ANY);
+ if ( !handler)
+ {
+ wxLogError(_("Can't save image to file '%s': unknown extension."),
+ filename);
+ return false;
+ }
+
+ return SaveFile(filename, handler->GetType());
+}
+
+bool wxImage::SaveFile( const wxString& WXUNUSED_UNLESS_STREAMS(filename),
+ wxBitmapType WXUNUSED_UNLESS_STREAMS(type) ) const
+{
+#if HAS_FILE_STREAMS
+ wxCHECK_MSG( Ok(), false, wxT("invalid image") );
+
+ ((wxImage*)this)->SetOption(wxIMAGE_OPTION_FILENAME, filename);
+
+ wxImageFileOutputStream stream(filename);
+
+ if ( stream.IsOk() )
+ {
+ wxBufferedOutputStream bstream( stream );
+ return SaveFile(bstream, type);
+ }
+#endif // HAS_FILE_STREAMS
+
+ return false;
+}
+
+bool wxImage::SaveFile( const wxString& WXUNUSED_UNLESS_STREAMS(filename),
+ const wxString& WXUNUSED_UNLESS_STREAMS(mimetype) ) const
+{
+#if HAS_FILE_STREAMS
+ wxCHECK_MSG( Ok(), false, wxT("invalid image") );
+
+ ((wxImage*)this)->SetOption(wxIMAGE_OPTION_FILENAME, filename);
+
+ wxImageFileOutputStream stream(filename);
+
+ if ( stream.IsOk() )
+ {
+ wxBufferedOutputStream bstream( stream );
+ return SaveFile(bstream, mimetype);
+ }
+#endif // HAS_FILE_STREAMS
+
+ return false;
+}
+
+bool wxImage::CanRead( const wxString& WXUNUSED_UNLESS_STREAMS(name) )
+{
+#if HAS_FILE_STREAMS
+ wxImageFileInputStream stream(name);
+ return CanRead(stream);
+#else
+ return false;
+#endif
+}
+
+int wxImage::GetImageCount( const wxString& WXUNUSED_UNLESS_STREAMS(name),
+ wxBitmapType WXUNUSED_UNLESS_STREAMS(type) )
+{
+#if HAS_FILE_STREAMS
+ wxImageFileInputStream stream(name);
+ if (stream.Ok())
+ return GetImageCount(stream, type);
+#endif
+
+ return 0;
+}
+
+#if wxUSE_STREAMS
+
+bool wxImage::CanRead( wxInputStream &stream )
+{
+ const wxList& list = GetHandlers();
+
+ for ( wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext() )
+ {
+ wxImageHandler *handler=(wxImageHandler*)node->GetData();
+ if (handler->CanRead( stream ))
+ return true;
+ }
+
+ return false;
+}
+
+int wxImage::GetImageCount( wxInputStream &stream, wxBitmapType type )
+{
+ wxImageHandler *handler;
+
+ if ( type == wxBITMAP_TYPE_ANY )
+ {
+ const wxList& list = GetHandlers();
+
+ for ( wxList::compatibility_iterator node = list.GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ handler = (wxImageHandler*)node->GetData();
+ if ( handler->CanRead(stream) )
+ {
+ const int count = handler->GetImageCount(stream);
+ if ( count >= 0 )
+ return count;
+ }
+
+ }
+
+ wxLogWarning(_("No handler found for image type."));
+ return 0;
+ }
+
+ handler = FindHandler(type);
+
+ if ( !handler )
+ {
+ wxLogWarning(_("No image handler for type %ld defined."), type);
+ return false;
+ }
+
+ if ( handler->CanRead(stream) )
+ {
+ return handler->GetImageCount(stream);
+ }
+ else
+ {
+ wxLogError(_("Image file is not of type %ld."), type);
+ return 0;
+ }
+}
+
+bool wxImage::DoLoad(wxImageHandler& handler, wxInputStream& stream, int index)
+{
+ if ( !handler.LoadFile(this, stream, true/*verbose*/, index) )
+ return false;
+
+ M_IMGDATA->m_type = handler.GetType();
+ return true;
+}
+
+bool wxImage::LoadFile( wxInputStream& stream, wxBitmapType type, int index )
+{
+ UnRef();
+
+ m_refData = new wxImageRefData;
+
+ wxImageHandler *handler;
+
+ if ( type == wxBITMAP_TYPE_ANY )
+ {
+ const wxList& list = GetHandlers();
+ for ( wxList::compatibility_iterator node = list.GetFirst();
+ node;
+ node = node->GetNext() )
+ {
+ handler = (wxImageHandler*)node->GetData();
+ if ( handler->CanRead(stream) && DoLoad(*handler, stream, index) )
+ return true;
+ }
+
+ wxLogWarning( _("No handler found for image type.") );
+
+ return false;
+ }
+ //else: have specific type
+
+ handler = FindHandler(type);
+ if ( !handler )
+ {
+ wxLogWarning( _("No image handler for type %ld defined."), type );
+ return false;
+ }
+
+ if ( stream.IsSeekable() && !handler->CanRead(stream) )
+ {
+ wxLogError(_("Image file is not of type %ld."), type);
+ return false;
+ }
+
+ return DoLoad(*handler, stream, index);
+}
+
+bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int index )
+{
+ UnRef();
+
+ m_refData = new wxImageRefData;
+
+ wxImageHandler *handler = FindHandlerMime(mimetype);
+
+ if ( !handler )
+ {
+ wxLogWarning( _("No image handler for type %s defined."), mimetype.GetData() );
+ return false;
+ }
+
+ if ( stream.IsSeekable() && !handler->CanRead(stream) )
+ {
+ wxLogError(_("Image file is not of type %s."), mimetype);
+ return false;
+ }
+
+ return DoLoad(*handler, stream, index);
+}
+
+bool wxImage::DoSave(wxImageHandler& handler, wxOutputStream& stream) const
+{
+ wxImage * const self = wx_const_cast(wxImage *, this);
+ if ( !handler.SaveFile(self, stream) )
+ return false;
+
+ M_IMGDATA->m_type = handler.GetType();
+ return true;
+}
+
+bool wxImage::SaveFile( wxOutputStream& stream, wxBitmapType type ) const
+{
+ wxCHECK_MSG( Ok(), false, wxT("invalid image") );
+
+ wxImageHandler *handler = FindHandler(type);
+ if ( !handler )
+ {
+ wxLogWarning( _("No image handler for type %d defined."), type );
+ return false;
+ }
+
+ return DoSave(*handler, stream);
+}