X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ff865c132a61e615bb7a157cd314d7f7428374a3..27db4210568ff8463f38e347614f40f238c9f660:/src/common/image.cpp diff --git a/src/common/image.cpp b/src/common/image.cpp index 289eb78759..d5ea5590e7 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -7,7 +7,7 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "image.h" #endif @@ -32,6 +32,7 @@ #include "wx/intl.h" #include "wx/module.h" #include "wx/hash.h" +#include "wx/utils.h" // For memcpy #include @@ -85,10 +86,10 @@ wxImageRefData::wxImageRefData() m_maskRed = 0; m_maskGreen = 0; m_maskBlue = 0; - m_hasMask = FALSE; + m_hasMask = false; - m_ok = FALSE; - m_static = FALSE; + m_ok = false; + m_static = false; } wxImageRefData::~wxImageRefData() @@ -156,45 +157,44 @@ wxImage::wxImage( const wxImage* image ) if (image) Ref(*image); } -void wxImage::Create( int width, int height, bool clear ) +bool wxImage::Create( int width, int height, bool clear ) { UnRef(); m_refData = new wxImageRefData(); M_IMGDATA->m_data = (unsigned char *) malloc( width*height*3 ); - if (M_IMGDATA->m_data) - { - if (clear) memset(M_IMGDATA->m_data, 0, width*height*3); - - M_IMGDATA->m_width = width; - M_IMGDATA->m_height = height; - M_IMGDATA->m_ok = TRUE; - } - else + if (!M_IMGDATA->m_data) { UnRef(); + return false; } + + if (clear) + memset(M_IMGDATA->m_data, 0, width*height*3); + + M_IMGDATA->m_width = width; + M_IMGDATA->m_height = height; + M_IMGDATA->m_ok = true; + + return true; } -void wxImage::Create( int width, int height, unsigned char* data, bool static_data ) +bool wxImage::Create( int width, int height, unsigned char* data, bool static_data ) { UnRef(); + wxCHECK_MSG( data, false, _T("NULL data in wxImage::Create") ); + m_refData = new wxImageRefData(); M_IMGDATA->m_data = data; - if (M_IMGDATA->m_data) - { - M_IMGDATA->m_width = width; - M_IMGDATA->m_height = height; - M_IMGDATA->m_ok = TRUE; - M_IMGDATA->m_static = static_data; - } - else - { - UnRef(); - } + M_IMGDATA->m_width = width; + M_IMGDATA->m_height = height; + M_IMGDATA->m_ok = true; + M_IMGDATA->m_static = static_data; + + return true; } void wxImage::Destroy() @@ -219,6 +219,11 @@ wxImage wxImage::Copy() const memcpy( data, GetData(), M_IMGDATA->m_width*M_IMGDATA->m_height*3 ); + // also copy the image options + wxImageRefData *imgData = (wxImageRefData *)image.m_refData; + imgData->m_optionNames = M_IMGDATA->m_optionNames; + imgData->m_optionValues = M_IMGDATA->m_optionValues; + return image; } @@ -226,7 +231,7 @@ wxImage wxImage::ShrinkBy( int xFactor , int yFactor ) const { if( xFactor == 1 && yFactor == 1 ) return Copy() ; - + wxImage image; wxCHECK_MSG( Ok(), image, wxT("invalid image") ); @@ -237,7 +242,7 @@ wxImage wxImage::ShrinkBy( int xFactor , int yFactor ) const long old_height = M_IMGDATA->m_height, old_width = M_IMGDATA->m_width; - + wxCHECK_MSG( (old_height > 0) && (old_width > 0), image, wxT("invalid old image size") ); @@ -260,14 +265,14 @@ wxImage wxImage::ShrinkBy( int xFactor , int yFactor ) const maskRed = M_IMGDATA->m_maskRed; maskGreen = M_IMGDATA->m_maskGreen; maskBlue =M_IMGDATA->m_maskBlue ; - + image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue ); } char unsigned *source_data = M_IMGDATA->m_data; char unsigned *target_data = data; - + for (long y = 0; y < height; y++) { for (long x = 0; x < width; x++) @@ -303,9 +308,9 @@ wxImage wxImage::ShrinkBy( int xFactor , int yFactor ) const } else { - *(target_data++) = avgRed / counter ; - *(target_data++) = avgGreen / counter ; - *(target_data++) = avgBlue / counter ; + *(target_data++) = (unsigned char)(avgRed / counter); + *(target_data++) = (unsigned char)(avgGreen / counter); + *(target_data++) = (unsigned char)(avgBlue / counter); } } } @@ -736,7 +741,7 @@ void wxImage::SetData( unsigned char *data ) newRefData->m_width = M_IMGDATA->m_width; newRefData->m_height = M_IMGDATA->m_height; newRefData->m_data = data; - newRefData->m_ok = TRUE; + 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; @@ -756,7 +761,7 @@ void wxImage::SetData( unsigned char *data, int new_width, int new_height ) newRefData->m_width = new_width; newRefData->m_height = new_height; newRefData->m_data = data; - newRefData->m_ok = TRUE; + 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; @@ -767,7 +772,7 @@ void wxImage::SetData( unsigned char *data, int new_width, int new_height ) newRefData->m_width = new_width; newRefData->m_height = new_height; newRefData->m_data = data; - newRefData->m_ok = TRUE; + newRefData->m_ok = true; } UnRef(); @@ -791,7 +796,7 @@ void wxImage::SetAlpha(int x, int y, unsigned char alpha) M_IMGDATA->m_alpha[y*w + x] = alpha; } -unsigned char wxImage::GetAlpha(int x, int y) +unsigned char wxImage::GetAlpha(int x, int y) const { wxCHECK_MSG( Ok() && HasAlpha(), 0, wxT("invalid image or no alpha channel") ); @@ -809,11 +814,10 @@ void wxImage::SetAlpha( unsigned char *alpha ) if ( !alpha ) { - alpha = (unsigned char *) - malloc(M_IMGDATA->m_width*M_IMGDATA->m_height*3); + alpha = (unsigned char *)malloc(M_IMGDATA->m_width*M_IMGDATA->m_height); } - delete [] M_IMGDATA->m_alpha; + free(M_IMGDATA->m_alpha); M_IMGDATA->m_alpha = alpha; } @@ -835,7 +839,7 @@ void wxImage::SetMaskColour( unsigned char r, unsigned char g, unsigned char b ) M_IMGDATA->m_maskRed = r; M_IMGDATA->m_maskGreen = g; M_IMGDATA->m_maskBlue = b; - M_IMGDATA->m_hasMask = TRUE; + M_IMGDATA->m_hasMask = true; } unsigned char wxImage::GetMaskRed() const @@ -868,7 +872,7 @@ void wxImage::SetMask( bool mask ) bool wxImage::HasMask() const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") ); + wxCHECK_MSG( Ok(), false, wxT("invalid image") ); return M_IMGDATA->m_hasMask; } @@ -893,16 +897,16 @@ bool wxImage::SetMaskFromImage(const wxImage& mask, // 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; + 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 ; + wxLogError( _("No unused colour in image being masked.") ); + return false ; } unsigned char *imgdata = GetData(); @@ -927,9 +931,49 @@ bool wxImage::SetMaskFromImage(const wxImage& mask, } SetMaskColour(r, g, b); - SetMask(TRUE); + 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; + } + + 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; + } + } + } - return TRUE; + free(M_IMGDATA->m_alpha); + M_IMGDATA->m_alpha = NULL; + + return true; } #if wxUSE_PALETTE @@ -939,7 +983,7 @@ bool wxImage::SetMaskFromImage(const wxImage& mask, bool wxImage::HasPalette() const { if (!Ok()) - return FALSE; + return false; return M_IMGDATA->m_palette.Ok(); } @@ -965,7 +1009,7 @@ void wxImage::SetOption(const wxString& name, const wxString& value) { wxCHECK_RET( Ok(), wxT("invalid image") ); - int idx = M_IMGDATA->m_optionNames.Index(name, FALSE); + int idx = M_IMGDATA->m_optionNames.Index(name, false); if (idx == wxNOT_FOUND) { M_IMGDATA->m_optionNames.Add(name); @@ -989,7 +1033,7 @@ wxString wxImage::GetOption(const wxString& name) const { wxCHECK_MSG( Ok(), wxEmptyString, wxT("invalid image") ); - int idx = M_IMGDATA->m_optionNames.Index(name, FALSE); + int idx = M_IMGDATA->m_optionNames.Index(name, false); if (idx == wxNOT_FOUND) return wxEmptyString; else @@ -1005,9 +1049,9 @@ int wxImage::GetOptionInt(const wxString& name) const bool wxImage::HasOption(const wxString& name) const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") ); + wxCHECK_MSG( Ok(), false, wxT("invalid image") ); - return (M_IMGDATA->m_optionNames.Index(name, FALSE) != wxNOT_FOUND); + return (M_IMGDATA->m_optionNames.Index(name, false) != wxNOT_FOUND); } bool wxImage::LoadFile( const wxString& filename, long type, int index ) @@ -1023,10 +1067,10 @@ bool wxImage::LoadFile( const wxString& filename, long type, int index ) { wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() ); - return FALSE; + return false; } #else // !wxUSE_STREAMS - return FALSE; + return false; #endif // wxUSE_STREAMS } @@ -1043,10 +1087,10 @@ bool wxImage::LoadFile( const wxString& filename, const wxString& mimetype, int { wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() ); - return FALSE; + return false; } #else // !wxUSE_STREAMS - return FALSE; + return false; #endif // wxUSE_STREAMS } @@ -1060,12 +1104,12 @@ bool wxImage::SaveFile( const wxString& filename ) const if (pHandler) { SaveFile(filename, pHandler->GetType()); - return TRUE; + return true; } wxLogError(_("Can't save image to file '%s': unknown extension."), filename.c_str()); - return FALSE; + return false; } bool wxImage::SaveFile( const wxString& filename, int type ) const @@ -1082,7 +1126,7 @@ bool wxImage::SaveFile( const wxString& filename, int type ) const } #endif // wxUSE_STREAMS - return FALSE; + return false; } bool wxImage::SaveFile( const wxString& filename, const wxString& mimetype ) const @@ -1099,7 +1143,7 @@ bool wxImage::SaveFile( const wxString& filename, const wxString& mimetype ) con } #endif // wxUSE_STREAMS - return FALSE; + return false; } bool wxImage::CanRead( const wxString &name ) @@ -1108,7 +1152,7 @@ bool wxImage::CanRead( const wxString &name ) wxFileInputStream stream(name); return CanRead(stream); #else - return FALSE; + return false; #endif } @@ -1129,14 +1173,14 @@ bool wxImage::CanRead( wxInputStream &stream ) { const wxList& list = GetHandlers(); - for ( wxList::Node *node = list.GetFirst(); node; node = node->GetNext() ) + for ( wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext() ) { wxImageHandler *handler=(wxImageHandler*)node->GetData(); if (handler->CanRead( stream )) - return TRUE; + return true; } - return FALSE; + return false; } int wxImage::GetImageCount( wxInputStream &stream, long type ) @@ -1147,7 +1191,7 @@ int wxImage::GetImageCount( wxInputStream &stream, long type ) { wxList &list=GetHandlers(); - for (wxList::Node *node = list.GetFirst(); node; node = node->GetNext()) + for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext()) { handler=(wxImageHandler*)node->GetData(); if ( handler->CanRead(stream) ) @@ -1164,7 +1208,7 @@ int wxImage::GetImageCount( wxInputStream &stream, long type ) if ( !handler ) { wxLogWarning(_("No image handler for type %d defined."), type); - return FALSE; + return false; } if ( handler->CanRead(stream) ) @@ -1190,16 +1234,16 @@ bool wxImage::LoadFile( wxInputStream& stream, long type, int index ) { wxList &list=GetHandlers(); - for ( wxList::Node *node = list.GetFirst(); node; node = node->GetNext() ) + for ( wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext() ) { handler=(wxImageHandler*)node->GetData(); if ( handler->CanRead(stream) ) - return handler->LoadFile(this, stream, TRUE/*verbose*/, index); + return handler->LoadFile(this, stream, true/*verbose*/, index); } wxLogWarning( _("No handler found for image type.") ); - return FALSE; + return false; } handler = FindHandler(type); @@ -1208,10 +1252,10 @@ bool wxImage::LoadFile( wxInputStream& stream, long type, int index ) { wxLogWarning( _("No image handler for type %d defined."), type ); - return FALSE; + return false; } - return handler->LoadFile(this, stream, TRUE/*verbose*/, index); + return handler->LoadFile(this, stream, true/*verbose*/, index); } bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int index ) @@ -1226,15 +1270,15 @@ bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int ind { wxLogWarning( _("No image handler for type %s defined."), mimetype.GetData() ); - return FALSE; + return false; } - return handler->LoadFile( this, stream, TRUE/*verbose*/, index ); + return handler->LoadFile( this, stream, true/*verbose*/, index ); } bool wxImage::SaveFile( wxOutputStream& stream, int type ) const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") ); + wxCHECK_MSG( Ok(), false, wxT("invalid image") ); wxImageHandler *handler = FindHandler(type); @@ -1242,7 +1286,7 @@ bool wxImage::SaveFile( wxOutputStream& stream, int type ) const { wxLogWarning( _("No image handler for type %d defined."), type ); - return FALSE; + return false; } return handler->SaveFile( (wxImage*)this, stream ); @@ -1250,7 +1294,7 @@ bool wxImage::SaveFile( wxOutputStream& stream, int type ) const bool wxImage::SaveFile( wxOutputStream& stream, const wxString& mimetype ) const { - wxCHECK_MSG( Ok(), FALSE, wxT("invalid image") ); + wxCHECK_MSG( Ok(), false, wxT("invalid image") ); wxImageHandler *handler = FindHandlerMime(mimetype); @@ -1258,7 +1302,7 @@ bool wxImage::SaveFile( wxOutputStream& stream, const wxString& mimetype ) const { wxLogWarning( _("No image handler for type %s defined."), mimetype.GetData() ); - return FALSE; + return false; } return handler->SaveFile( (wxImage*)this, stream ); @@ -1267,9 +1311,6 @@ bool wxImage::SaveFile( wxOutputStream& stream, const wxString& mimetype ) const void wxImage::AddHandler( wxImageHandler *handler ) { - // make sure that the memory will be freed at the program end - sm_handlers.DeleteContents(TRUE); - // Check for an existing handler of the type being added. if (FindHandler( handler->GetType() ) == 0) { @@ -1291,9 +1332,6 @@ void wxImage::AddHandler( wxImageHandler *handler ) void wxImage::InsertHandler( wxImageHandler *handler ) { - // make sure that the memory will be freed at the program end - sm_handlers.DeleteContents(TRUE); - // Check for an existing handler of the type being added. if (FindHandler( handler->GetType() ) == 0) { @@ -1314,15 +1352,16 @@ bool wxImage::RemoveHandler( const wxString& name ) if (handler) { sm_handlers.DeleteObject(handler); - return TRUE; + delete handler; + return true; } else - return FALSE; + return false; } wxImageHandler *wxImage::FindHandler( const wxString& name ) { - wxNode *node = sm_handlers.GetFirst(); + wxList::compatibility_iterator node = sm_handlers.GetFirst(); while (node) { wxImageHandler *handler = (wxImageHandler*)node->GetData(); @@ -1335,7 +1374,7 @@ wxImageHandler *wxImage::FindHandler( const wxString& name ) wxImageHandler *wxImage::FindHandler( const wxString& extension, long bitmapType ) { - wxNode *node = sm_handlers.GetFirst(); + wxList::compatibility_iterator node = sm_handlers.GetFirst(); while (node) { wxImageHandler *handler = (wxImageHandler*)node->GetData(); @@ -1349,7 +1388,7 @@ wxImageHandler *wxImage::FindHandler( const wxString& extension, long bitmapType wxImageHandler *wxImage::FindHandler( long bitmapType ) { - wxNode *node = sm_handlers.GetFirst(); + wxList::compatibility_iterator node = sm_handlers.GetFirst(); while (node) { wxImageHandler *handler = (wxImageHandler *)node->GetData(); @@ -1361,11 +1400,11 @@ wxImageHandler *wxImage::FindHandler( long bitmapType ) wxImageHandler *wxImage::FindHandlerMime( const wxString& mimetype ) { - wxNode *node = sm_handlers.GetFirst(); + wxList::compatibility_iterator node = sm_handlers.GetFirst(); while (node) { wxImageHandler *handler = (wxImageHandler *)node->GetData(); - if (handler->GetMimeType().IsSameAs(mimetype, FALSE)) return handler; + if (handler->GetMimeType().IsSameAs(mimetype, false)) return handler; node = node->GetNext(); } return 0; @@ -1380,17 +1419,34 @@ void wxImage::InitStandardHandlers() void wxImage::CleanUpHandlers() { - wxNode *node = sm_handlers.GetFirst(); + wxList::compatibility_iterator node = sm_handlers.GetFirst(); while (node) { wxImageHandler *handler = (wxImageHandler *)node->GetData(); - wxNode *next = node->GetNext(); + wxList::compatibility_iterator next = node->GetNext(); delete handler; - delete node; node = next; } + + sm_handlers.Clear(); } +wxString wxImage::GetImageExtWildcard() +{ + wxString fmts; + + wxList& Handlers = wxImage::GetHandlers(); + wxList::compatibility_iterator Node = Handlers.GetFirst(); + while ( Node ) + { + wxImageHandler* Handler = (wxImageHandler*)Node->GetData(); + fmts += wxT("*.") + Handler->GetExtension(); + Node = Node->GetNext(); + if ( Node ) fmts += wxT(";"); + } + + return wxT("(") + fmts + wxT(")|") + fmts; +} //----------------------------------------------------------------------------- // wxImageHandler @@ -1401,12 +1457,12 @@ IMPLEMENT_ABSTRACT_CLASS(wxImageHandler,wxObject) #if wxUSE_STREAMS bool wxImageHandler::LoadFile( wxImage *WXUNUSED(image), wxInputStream& WXUNUSED(stream), bool WXUNUSED(verbose), int WXUNUSED(index) ) { - return FALSE; + return false; } bool wxImageHandler::SaveFile( wxImage *WXUNUSED(image), wxOutputStream& WXUNUSED(stream), bool WXUNUSED(verbose) ) { - return FALSE; + return false; } int wxImageHandler::GetImageCount( wxInputStream& WXUNUSED(stream) ) @@ -1424,7 +1480,7 @@ bool wxImageHandler::CanRead( const wxString& name ) wxLogError( _("Can't check image format of file '%s': file does not exist."), name.c_str() ); - return FALSE; + return false; } bool wxImageHandler::CallDoCanRead(wxInputStream& stream) @@ -1433,7 +1489,7 @@ bool wxImageHandler::CallDoCanRead(wxInputStream& stream) if ( posOld == wxInvalidOffset ) { // can't test unseekable stream - return FALSE; + return false; } bool ok = DoCanRead(stream); @@ -1444,7 +1500,7 @@ bool wxImageHandler::CallDoCanRead(wxInputStream& stream) 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; @@ -1452,37 +1508,6 @@ bool wxImageHandler::CallDoCanRead(wxInputStream& stream) #endif // wxUSE_STREAMS - - -//----------------------------------------------------------------------------- -// Deprecated wxBitmap conversion routines -//----------------------------------------------------------------------------- - -#if WXWIN_COMPATIBILITY_2_2 && wxUSE_GUI - -#ifdef __WXGTK__ -wxBitmap wxImage::ConvertToMonoBitmap( unsigned char red, unsigned char green, unsigned char blue ) const -{ - wxImage mono = this->ConvertToMono( red, green, blue ); - wxBitmap bitmap( mono, 1 ); - return bitmap; -} -#endif - -wxBitmap wxImage::ConvertToBitmap() const -{ - wxBitmap bitmap( *this ); - return bitmap; -} - -wxImage::wxImage( const wxBitmap &bitmap ) -{ - *this = bitmap.ConvertToImage(); -} - -#endif // WXWIN_COMPATIBILITY_2_2 && wxUSE_GUI - - // ---------------------------------------------------------------------------- // image histogram stuff // ---------------------------------------------------------------------------- @@ -1511,8 +1536,8 @@ wxImageHistogram::FindFirstUnusedColour(unsigned char *r, b2++; if ( b2 >= 255 ) { - wxLogError(_("GetUnusedColour:: No Unused Color in image ") ); - return FALSE; + wxLogError(_("No unused colour in image.") ); + return false; } } } @@ -1527,7 +1552,7 @@ wxImageHistogram::FindFirstUnusedColour(unsigned char *r, if ( b ) *b = b2; - return TRUE; + return true; } bool @@ -1819,8 +1844,8 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i w3 * *(v3++) + w4 * *(v4++)) / (w1 + w2 + w3 + w4) ); *(dst++) = (unsigned char) - ( (w1 * *(v1++) + w2 * *(v2++) + - w3 * *(v3++) + w4 * *(v4++)) / + ( (w1 * *v1 + w2 * *v2 + + w3 * *v3 + w4 * *v4) / (w1 + w2 + w3 + w4) ); } } @@ -1850,7 +1875,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i unsigned char *p = data[ys] + (3 * xs); *(dst++) = *(p++); *(dst++) = *(p++); - *(dst++) = *(p++); + *(dst++) = *p; } else { @@ -1880,7 +1905,7 @@ class wxImageModule: public wxModule DECLARE_DYNAMIC_CLASS(wxImageModule) public: wxImageModule() {} - bool OnInit() { wxImage::InitStandardHandlers(); return TRUE; }; + bool OnInit() { wxImage::InitStandardHandlers(); return true; }; void OnExit() { wxImage::CleanUpHandlers(); }; };