X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6c28fd3379ca2de91953a43f609cf3d726107bec..a204e0b5da552017a4932b77d0b13b7c9d0bc23b:/src/common/image.cpp diff --git a/src/common/image.cpp b/src/common/image.cpp index a798ea580b..ee46631c93 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -28,7 +28,6 @@ #include "wx/log.h" #include "wx/app.h" #include "wx/filefn.h" -#include "wx/filesys.h" #include "wx/wfstream.h" #include "wx/intl.h" #include "wx/module.h" @@ -59,7 +58,9 @@ public: unsigned char m_maskRed,m_maskGreen,m_maskBlue; bool m_ok; bool m_static; +#if wxUSE_PALETTE wxPalette m_palette; +#endif // wxUSE_PALETTE wxArrayString m_optionNames; wxArrayString m_optionValues; }; @@ -211,7 +212,14 @@ wxImage wxImage::Scale( int width, int height ) const wxCHECK_MSG( Ok(), image, wxT("invalid image") ); - wxCHECK_MSG( (width > 0) && (height > 0), image, wxT("invalid image size") ); + // can't scale to/from 0 size + wxCHECK_MSG( (width > 0) && (height > 0), image, + wxT("invalid new image size") ); + + 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") ); image.Create( width, height ); @@ -220,26 +228,52 @@ wxImage wxImage::Scale( int width, int height ) const 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 ); - - long old_height = M_IMGDATA->m_height; - long old_width = M_IMGDATA->m_width; + { + 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; +#if 0 + // This is nonsense, RR. + + // We do (x, y) -> (x, y)*oldSize/newSize but the valid values of x and y + // are from 0 to size-1, hence all decrement the sizes + long old_old_width = old_width; + old_height--; + old_width--; + height--; + width--; + for ( long j = 0; j <= height; j++ ) + { + // don't crash for images with height == 1 + long y_offset = height ? (j * old_height / height)* old_old_width : 0; + + for ( long i = 0; i <= width; i++ ) + { + long x_offset = width ? (i * old_width) / width : 0; + + memcpy( target_data, source_data + 3*(y_offset + x_offset), 3 ); + target_data += 3; + } + } +#else for (long j = 0; j < height; j++) { - long y_offset = (j * (old_height-1) / (height-1)) * old_width; + long y_offset = (j * old_height / height) * old_width; for (long i = 0; i < width; i++) { memcpy( target_data, - source_data + 3*(y_offset + ((i * (old_width-1) )/ (width-1))), + source_data + 3*(y_offset + ((i * old_width )/ width)), 3 ); target_data += 3; } } +#endif return image; } @@ -686,6 +720,100 @@ int wxImage::GetHeight() const 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 @@ -710,6 +838,8 @@ void wxImage::SetPalette(const wxPalette& palette) M_IMGDATA->m_palette = palette; } +#endif // wxUSE_PALETTE + // Option functions (arbitrary name/value mapping) void wxImage::SetOption(const wxString& name, const wxString& value) { @@ -763,22 +893,18 @@ bool wxImage::HasOption(const wxString& name) const bool wxImage::LoadFile( const wxString& filename, long type ) { #if wxUSE_STREAMS - // We want to use wxFileSystem for virtual FS compatibility - wxFileSystem fsys; - wxFSFile *file = fsys.OpenFile(filename); - if (!file) + if (wxFileExists(filename)) { - wxLogError(_("Can't open file '%s'"), filename.c_str()); - return FALSE; + wxFileInputStream stream(filename); + wxBufferedInputStream bstream( stream ); + return LoadFile(bstream, type); } - wxInputStream *stream = file->GetStream(); - if (!stream) + else { - wxLogError(_("Can't open stream for file '%s'"), filename.c_str()); + wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() ); + return FALSE; } - - return LoadFile(*stream, type); #else // !wxUSE_STREAMS return FALSE; #endif // wxUSE_STREAMS @@ -787,21 +913,18 @@ bool wxImage::LoadFile( const wxString& filename, long type ) bool wxImage::LoadFile( const wxString& filename, const wxString& mimetype ) { #if wxUSE_STREAMS - // We want to use wxFileSystem for virtual FS compatibility - wxFileSystem fsys; - wxFSFile *file = fsys.OpenFile(filename); - if (!file) + if (wxFileExists(filename)) { - wxLogError(_("Can't open file '%s'"), filename.c_str()); - return FALSE; + wxFileInputStream stream(filename); + wxBufferedInputStream bstream( stream ); + return LoadFile(bstream, mimetype); } - wxInputStream *stream = file->GetStream(); - if (!stream) + else { - wxLogError(_("Can't open stream for file '%s'"), filename.c_str()); + wxLogError( _("Can't load image from file '%s': file does not exist."), filename.c_str() ); + return FALSE; } - return LoadFile(*stream, mimetype); #else // !wxUSE_STREAMS return FALSE; #endif // wxUSE_STREAMS @@ -1032,7 +1155,7 @@ wxImageHandler *wxImage::FindHandlerMime( const wxString& mimetype ) void wxImage::InitStandardHandlers() { AddHandler(new wxBMPHandler); -#if !defined(__WXGTK__) && !defined(__WXMOTIF__) +#if wxUSE_XPM && !defined(__WXGTK__) && !defined(__WXMOTIF__) AddHandler(new wxXPMHandler); #endif }