Create( width, height, data, static_data );
}
-wxImage::wxImage( const wxString& name, long type )
+wxImage::wxImage( const wxString& name, long type, int index )
{
- LoadFile( name, type );
+ LoadFile( name, type, index );
}
-wxImage::wxImage( const wxString& name, const wxString& mimetype )
+wxImage::wxImage( const wxString& name, const wxString& mimetype, int index )
{
- LoadFile( name, mimetype );
+ LoadFile( name, mimetype, index );
}
#if wxUSE_STREAMS
-wxImage::wxImage( wxInputStream& stream, long type )
+wxImage::wxImage( wxInputStream& stream, long type, int index )
{
- LoadFile( stream, type );
+ LoadFile( stream, type, index );
}
-wxImage::wxImage( wxInputStream& stream, const wxString& mimetype )
+wxImage::wxImage( wxInputStream& stream, const wxString& mimetype, int index )
{
- LoadFile( stream, mimetype );
+ LoadFile( stream, mimetype, index );
}
#endif // wxUSE_STREAMS
wxImage::wxImage( const wxImage& image )
+ : wxObject()
{
Ref(image);
}
wxCHECK_MSG( data, image, wxT("unable to create image") );
- if (M_IMGDATA->m_hasMask)
- image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
+ image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
+ image.SetMask( M_IMGDATA->m_hasMask );
memcpy( data, GetData(), M_IMGDATA->m_width*M_IMGDATA->m_height*3 );
}
#endif
+ // In case this is a cursor, make sure the hotspot is scalled accordingly:
+ if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_X) )
+ image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_X,
+ (GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_X)*width)/old_width);
+ if ( HasOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y) )
+ image.SetOption(wxIMAGE_OPTION_CUR_HOTSPOT_Y,
+ (GetOptionInt(wxIMAGE_OPTION_CUR_HOTSPOT_Y)*height)/old_height);
+
return image;
}
}
-bool wxImage::GetUnusedColour ( unsigned char * r, unsigned char * g, unsigned char * b )
+bool wxImage::FindFirstUnusedColour(
+ unsigned char *r, unsigned char *g, unsigned char *b,
+ unsigned char startR, unsigned char startG, unsigned char startB) const
{
- wxHashTable hTable;
+ wxImageHistogram histogram;
unsigned long key;
- ComputeHistogram( hTable );
+ ComputeHistogram(histogram);
- // start with blackest color and work to lightest
- // 0,0,0 is quite likely to be a used color
- unsigned char r2 = 1;
- unsigned char g2 = 0;
- unsigned char b2 = 0;
+ unsigned char r2 = startR;
+ unsigned char g2 = startG;
+ unsigned char b2 = startB;
key = (r2 << 16) | (g2 << 8) | b2;
- while ( (wxHNode *) hTable.Get(key) )
+ while ( histogram.find(key) != histogram.end() )
{
// color already used
- r2 ++ ;
+ r2++;
if ( r2 >= 255 )
{
r2 = 0;
- g2 ++ ;
+ g2++;
if ( g2 >= 255 )
{
- g2 = 0 ;
- b2 ++ ;
+ g2 = 0;
+ b2++;
if ( b2 >= 255 )
{
wxLogError( _("GetUnusedColour:: No Unused Color in image ") );
key = (r2 << 16) | (g2 << 8) | b2;
}
+ if (r) *r = r2;
+ if (g) *g = g2;
+ if (b) *b = b2;
+
return TRUE;
}
-bool wxImage::ApplyMask ( const wxImage & mask )
+bool wxImage::SetMaskFromImage(const wxImage& mask,
+ unsigned char mr, unsigned char mg, unsigned char mb)
{
- // what to do if we already have a mask ??
- if (M_IMGDATA->m_hasMask || mask.HasMask() )
- {
- wxLogError( _("Image already masked") );
- return FALSE;
- }
-
// check that the images are the same size
if ( (M_IMGDATA->m_height != mask.GetHeight() ) || (M_IMGDATA->m_width != mask.GetWidth () ) )
{
// find unused colour
unsigned char r,g,b ;
- if (!GetUnusedColour (&r, &g, &b))
+ if (!FindFirstUnusedColour(&r, &g, &b))
{
wxLogError( _("No Unused Color in image being masked") );
return FALSE ;
const int h = GetHeight();
for (int j = 0; j < h; j++)
+ {
for (int i = 0; i < w; i++)
{
- if ((maskdata[0] > 128) && (maskdata[1] > 128) && (maskdata[2] > 128 ))
+ if ((maskdata[0] == mr) && (maskdata[1] == mg) && (maskdata[2] == mb))
{
imgdata[0] = r;
imgdata[1] = g;
imgdata += 3;
maskdata += 3;
}
+ }
- M_IMGDATA->m_maskRed = r;
- M_IMGDATA->m_maskGreen = g;
- M_IMGDATA->m_maskBlue = b;
- M_IMGDATA->m_hasMask = TRUE;
+ SetMaskColour(r, g, b);
+ SetMask(TRUE);
return TRUE;
}
return (M_IMGDATA->m_optionNames.Index(name, FALSE) != wxNOT_FOUND);
}
-bool wxImage::LoadFile( const wxString& filename, long type )
+bool wxImage::LoadFile( const wxString& filename, long type, int index )
{
#if wxUSE_STREAMS
if (wxFileExists(filename))
{
wxFileInputStream stream(filename);
wxBufferedInputStream bstream( stream );
- return LoadFile(bstream, type);
+ return LoadFile(bstream, type, index);
}
else
{
#endif // wxUSE_STREAMS
}
-bool wxImage::LoadFile( const wxString& filename, const wxString& mimetype )
+bool wxImage::LoadFile( const wxString& filename, const wxString& mimetype, int index )
{
#if wxUSE_STREAMS
if (wxFileExists(filename))
{
wxFileInputStream stream(filename);
wxBufferedInputStream bstream( stream );
- return LoadFile(bstream, mimetype);
+ return LoadFile(bstream, mimetype, index);
}
else
{
#endif // wxUSE_STREAMS
}
-bool wxImage::SaveFile( const wxString& filename, int type )
+
+
+bool wxImage::SaveFile( const wxString& filename ) const
+{
+ wxString ext = filename.AfterLast('.').Lower();
+
+ wxImageHandler * pHandler = FindHandler(ext, -1);
+ if (pHandler)
+ {
+ SaveFile(filename, pHandler->GetType());
+ return TRUE;
+ }
+
+ wxLogError(_("Can't save image to file '%s': unknown extension."), filename.c_str());
+
+ return FALSE;
+}
+
+bool wxImage::SaveFile( const wxString& filename, int type ) const
{
#if wxUSE_STREAMS
+ ((wxImage*)this)->SetOption(wxIMAGE_OPTION_FILENAME, filename);
+
wxFileOutputStream stream(filename);
if ( stream.LastError() == wxStream_NOERROR )
return FALSE;
}
-bool wxImage::SaveFile( const wxString& filename, const wxString& mimetype )
+bool wxImage::SaveFile( const wxString& filename, const wxString& mimetype ) const
{
#if wxUSE_STREAMS
+ ((wxImage*)this)->SetOption(wxIMAGE_OPTION_FILENAME, filename);
+
wxFileOutputStream stream(filename);
if ( stream.LastError() == wxStream_NOERROR )
#endif
}
+int wxImage::GetImageCount( const wxString &name, long type )
+{
+#if wxUSE_STREAMS
+ wxFileInputStream stream(name);
+ return GetImageCount(stream, type);
+#else
+ return 0;
+#endif
+}
+
#if wxUSE_STREAMS
bool wxImage::CanRead( wxInputStream &stream )
{
- wxList &list=GetHandlers();
+ const wxList& list = GetHandlers();
- for ( wxList::Node *node = list.GetFirst(); node; node = node->GetNext() )
+ for ( wxList::Node *node = list.GetFirst(); node; node = node->GetNext() )
{
- wxImageHandler *handler=(wxImageHandler*)node->GetData();
- if (handler->CanRead( stream ))
- return TRUE;
+ wxImageHandler *handler=(wxImageHandler*)node->GetData();
+ if (handler->CanRead( stream ))
+ return TRUE;
}
- return FALSE;
+ return FALSE;
}
-bool wxImage::LoadFile( wxInputStream& stream, long type )
+int wxImage::GetImageCount( wxInputStream &stream, long type )
+{
+ wxImageHandler *handler;
+
+ if ( type == wxBITMAP_TYPE_ANY )
+ {
+ wxList &list=GetHandlers();
+
+ for (wxList::Node *node = list.GetFirst(); node; node = node->GetNext())
+ {
+ handler=(wxImageHandler*)node->GetData();
+ if ( handler->CanRead(stream) )
+ return handler->GetImageCount(stream);
+
+ }
+
+ wxLogWarning(_("No handler found for image type."));
+ return 0;
+ }
+
+ handler = FindHandler(type);
+
+ if ( !handler )
+ {
+ wxLogWarning(_("No image handler for type %d defined."), type);
+ return FALSE;
+ }
+
+ if ( handler->CanRead(stream) )
+ {
+ return handler->GetImageCount(stream);
+ }
+ else
+ {
+ wxLogError(_("Image file is not of type %d."), type);
+ return 0;
+ }
+}
+
+bool wxImage::LoadFile( wxInputStream& stream, long type, int index )
{
UnRef();
wxImageHandler *handler;
- if (type==wxBITMAP_TYPE_ANY)
+ if ( type == wxBITMAP_TYPE_ANY )
{
wxList &list=GetHandlers();
for ( wxList::Node *node = list.GetFirst(); node; node = node->GetNext() )
{
handler=(wxImageHandler*)node->GetData();
- if (handler->CanRead( stream ))
- return handler->LoadFile( this, stream );
+ if ( handler->CanRead(stream) )
+ return handler->LoadFile(this, stream, TRUE/*verbose*/, index);
}
return FALSE;
}
- return handler->LoadFile( this, stream );
+ return handler->LoadFile(this, stream, TRUE/*verbose*/, index);
}
-bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype )
+bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int index )
{
UnRef();
return FALSE;
}
- return handler->LoadFile( this, stream );
+ return handler->LoadFile( this, stream, TRUE/*verbose*/, index );
}
-bool wxImage::SaveFile( wxOutputStream& stream, int type )
+bool wxImage::SaveFile( wxOutputStream& stream, int type ) const
{
wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") );
return FALSE;
}
- return handler->SaveFile( this, stream );
+ return handler->SaveFile( (wxImage*)this, stream );
}
-bool wxImage::SaveFile( wxOutputStream& stream, const wxString& mimetype )
+bool wxImage::SaveFile( wxOutputStream& stream, const wxString& mimetype ) const
{
wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") );
return FALSE;
}
- return handler->SaveFile( this, stream );
+ return handler->SaveFile( (wxImage*)this, stream );
}
#endif // wxUSE_STREAMS
void wxImage::InitStandardHandlers()
{
+#if wxUSE_STREAMS
AddHandler(new wxBMPHandler);
+#endif // wxUSE_STREAMS
+
#if wxUSE_XPM && !defined(__WXGTK__) && !defined(__WXMOTIF__)
AddHandler(new wxXPMHandler);
#endif
return CanRead(stream);
}
- else {
- wxLogError( _("Can't check image format of file '%s': file does not exist."), name.c_str() );
+ wxLogError( _("Can't check image format of file '%s': file does not exist."), name.c_str() );
+
+ return FALSE;
+}
+
+bool wxImageHandler::CallDoCanRead(wxInputStream& stream)
+{
+ off_t posOld = stream.TellI();
+ if ( posOld == wxInvalidOffset )
+ {
+ // can't test unseekable stream
+ return FALSE;
+ }
+
+ bool ok = DoCanRead(stream);
+
+ // restore the old position to be able to test other formats and so on
+ if ( stream.SeekI(posOld) == wxInvalidOffset )
+ {
+ wxLogDebug(_T("Failed to rewind the stream in wxImageHandler!"));
+ // reading would fail anyhow as we're not at the right position
return FALSE;
}
-// return FALSE;
+
+ return ok;
}
#endif // wxUSE_STREAMS
//-----------------------------------------------------------------------------
-// wxBitmap convertion routines
+// Deprecated wxBitmap convertion routines
//-----------------------------------------------------------------------------
-#if wxUSE_GUI
+#if WXWIN_COMPATIBILITY_2_2 && wxUSE_GUI
#ifdef __WXGTK__
wxBitmap wxImage::ConvertToMonoBitmap( unsigned char red, unsigned char green, unsigned char blue ) const
*this = bitmap.ConvertToImage();
}
-#endif
-
-
-
-// A module to allow wxImage initialization/cleanup
-// without calling these functions from app.cpp or from
-// the user's application.
-
-class wxImageModule: public wxModule
-{
-DECLARE_DYNAMIC_CLASS(wxImageModule)
-public:
- wxImageModule() {}
- bool OnInit() { wxImage::InitStandardHandlers(); return TRUE; };
- void OnExit() { wxImage::CleanUpHandlers(); };
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxImageModule, wxModule)
+#endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_GUI
//-----------------------------------------------------------------------------
// less, in this case it would be invoked as CountColours(256)). Default
// value for stopafter is -1 (don't care).
//
-unsigned long wxImage::CountColours( unsigned long stopafter )
+unsigned long wxImage::CountColours( unsigned long stopafter ) const
{
wxHashTable h;
wxObject dummy;
}
-// GRG, Dic/99
-// Computes the histogram of the image and fills a hash table, indexed
-// with integer keys built as 0xRRGGBB, containing wxHNode objects. Each
-// wxHNode contains an 'index' (useful to build a palette with the image
-// colours) and a 'value', which is the number of pixels in the image with
-// that colour.
-//
-unsigned long wxImage::ComputeHistogram( wxHashTable &h )
+unsigned long wxImage::ComputeHistogram( wxImageHistogram &h ) const
{
unsigned char r, g, b;
unsigned char *p;
unsigned long size, nentries, key;
- wxHNode *hnode;
+
+ h.clear();
p = GetData();
size = GetWidth() * GetHeight();
b = *(p++);
key = (r << 16) | (g << 8) | b;
- hnode = (wxHNode *) h.Get(key);
-
- if (hnode)
- hnode->value++;
- else
- {
- hnode = new wxHNode();
- hnode->index = nentries++;
- hnode->value = 1;
-
- h.Put(key, (wxObject *)hnode);
- }
+ wxImageHistogramEntry& entry = h[key];
+ if ( entry.value++ == 0 )
+ entry.index = nentries++;
}
return nentries;
return rotated;
}
+
+
+
+
+// A module to allow wxImage initialization/cleanup
+// without calling these functions from app.cpp or from
+// the user's application.
+
+class wxImageModule: public wxModule
+{
+DECLARE_DYNAMIC_CLASS(wxImageModule)
+public:
+ wxImageModule() {}
+ bool OnInit() { wxImage::InitStandardHandlers(); return TRUE; };
+ void OnExit() { wxImage::CleanUpHandlers(); };
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxImageModule, wxModule)
+
+
#endif // wxUSE_IMAGE