X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/e26d5213eccaaf7806e0b0594b642b12a01209e2..7b0ccb8a603b4f97740acc65d9429bb58f7ba1bd:/src/common/image.cpp diff --git a/src/common/image.cpp b/src/common/image.cpp index be43304ba9..cf7eb9538b 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -39,12 +39,12 @@ #define HAS_FILE_STREAMS (wxUSE_STREAMS && (wxUSE_FILE || wxUSE_FFILE)) #if HAS_FILE_STREAMS - #if wxUSE_FILE - typedef wxFileInputStream wxImageFileInputStream; - typedef wxFileOutputStream wxImageFileOutputStream; - #elif wxUSE_FFILE + #if wxUSE_FFILE typedef wxFFileInputStream wxImageFileInputStream; typedef wxFFileOutputStream wxImageFileOutputStream; + #elif wxUSE_FILE + typedef wxFileInputStream wxImageFileInputStream; + typedef wxFileOutputStream wxImageFileOutputStream; #endif // wxUSE_FILE/wxUSE_FFILE #endif // HAS_FILE_STREAMS @@ -538,13 +538,8 @@ wxImage wxImage::ResampleBox(int width, int height) const const int scale_factor_x_2 = (int)(scale_factor_x / 2); const int scale_factor_y_2 = (int)(scale_factor_y / 2); - // If we want good-looking results we need to pre-blur the image a bit first - wxImage src_image(*this); - src_image = src_image.BlurHorizontal(scale_factor_x_2); - src_image = src_image.BlurVertical(scale_factor_y_2); - - unsigned char* src_data = src_image.GetData(); - unsigned char* src_alpha = src_image.GetAlpha(); + unsigned char* src_data = M_IMGDATA->m_data; + unsigned char* src_alpha = M_IMGDATA->m_alpha; unsigned char* dst_data = ret_image.GetData(); unsigned char* dst_alpha = NULL; @@ -576,7 +571,7 @@ wxImage wxImage::ResampleBox(int width, int height) const j++ ) { // We don't care to average pixels that don't exist (edges) - if ( j < 0 || j > M_IMGDATA->m_height ) + if ( j < 0 || j > M_IMGDATA->m_height - 1 ) continue; for ( int i = int(src_x - scale_factor_x/2.0 + 1); @@ -584,11 +579,11 @@ wxImage wxImage::ResampleBox(int width, int height) const i++ ) { // Don't average edge pixels - if ( i < 0 || i > M_IMGDATA->m_width ) + if ( i < 0 || i > M_IMGDATA->m_width - 1 ) continue; // Calculate the actual index in our source pixels - src_pixel_index = src_y * M_IMGDATA->m_width + src_x; + src_pixel_index = j * M_IMGDATA->m_width + i; sum_r += src_data[src_pixel_index * 3 + 0]; sum_g += src_data[src_pixel_index * 3 + 1]; @@ -675,13 +670,13 @@ wxImage wxImage::ResampleBicubic(int width, int height) const for ( int dsty = 0; dsty < height; dsty++ ) { // We need to calculate the source pixel to interpolate from - Y-axis - double srcpixy = dsty * M_IMGDATA->m_height / height; + double srcpixy = double(dsty * M_IMGDATA->m_height) / height; double dy = srcpixy - (int)srcpixy; for ( int dstx = 0; dstx < width; dstx++ ) { // X-axis of pixel to interpolate from - double srcpixx = dstx * M_IMGDATA->m_width / width; + double srcpixx = double(dstx * M_IMGDATA->m_width) / width; double dx = srcpixx - (int)srcpixx; // Sums for each color channel @@ -743,7 +738,7 @@ wxImage wxImage::ResampleBicubic(int width, int height) const } // Blur in the horizontal direction -wxImage wxImage::BlurHorizontal(int blurRadius) +wxImage wxImage::BlurHorizontal(int blurRadius) const { wxImage ret_image; ret_image.Create(M_IMGDATA->m_width, M_IMGDATA->m_height, false); @@ -754,20 +749,17 @@ wxImage wxImage::BlurHorizontal(int blurRadius) unsigned char* dst_alpha = NULL; // Check for a mask or alpha - if ( M_IMGDATA->m_hasMask ) + if ( src_alpha ) + { + ret_image.SetAlpha(); + dst_alpha = ret_image.GetAlpha(); + } + else if ( M_IMGDATA->m_hasMask ) { ret_image.SetMaskColour(M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue); } - else - { - if ( src_alpha ) - { - ret_image.SetAlpha(); - dst_alpha = ret_image.GetAlpha(); - } - } // number of pixels we average over const int blurArea = blurRadius*2 + 1; @@ -861,7 +853,7 @@ wxImage wxImage::BlurHorizontal(int blurRadius) } // Blur in the vertical direction -wxImage wxImage::BlurVertical(int blurRadius) +wxImage wxImage::BlurVertical(int blurRadius) const { wxImage ret_image; ret_image.Create(M_IMGDATA->m_width, M_IMGDATA->m_height, false); @@ -872,20 +864,17 @@ wxImage wxImage::BlurVertical(int blurRadius) unsigned char* dst_alpha = NULL; // Check for a mask or alpha - if ( M_IMGDATA->m_hasMask ) + if ( src_alpha ) + { + ret_image.SetAlpha(); + dst_alpha = ret_image.GetAlpha(); + } + else if ( M_IMGDATA->m_hasMask ) { ret_image.SetMaskColour(M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue); } - else - { - if ( src_alpha ) - { - ret_image.SetAlpha(); - dst_alpha = ret_image.GetAlpha(); - } - } // number of pixels we average over const int blurArea = blurRadius*2 + 1; @@ -979,7 +968,7 @@ wxImage wxImage::BlurVertical(int blurRadius) } // The new blur function -wxImage wxImage::Blur(int blurRadius) +wxImage wxImage::Blur(int blurRadius) const { wxImage ret_image; ret_image.Create(M_IMGDATA->m_width, M_IMGDATA->m_height, false); @@ -1294,6 +1283,26 @@ void wxImage::Paste( const wxImage &image, int x, int y ) return; } + // Copy over the alpha channel from the original image + if ( image.HasAlpha() ) + { + if ( !HasAlpha() ) + InitAlpha(); + + unsigned char* source_data = image.GetAlpha() + xx + yy*image.GetWidth(); + int source_step = image.GetWidth(); + + unsigned char* target_data = GetAlpha() + (x+xx) + (y+yy)*M_IMGDATA->m_width; + int target_step = M_IMGDATA->m_width; + + for (int j = 0; j < height; j++, + source_data += source_step, + target_data += target_step) + { + memcpy( target_data, source_data, width ); + } + } + if (!HasMask() && image.HasMask()) { unsigned char r = image.GetMaskRed(); @@ -1671,7 +1680,9 @@ void wxImage::SetAlpha( unsigned char *alpha, bool static_data ) alpha = (unsigned char *)malloc(M_IMGDATA->m_width*M_IMGDATA->m_height); } - free(M_IMGDATA->m_alpha); + if( !M_IMGDATA->m_staticAlpha ) + free(M_IMGDATA->m_alpha); + M_IMGDATA->m_alpha = alpha; M_IMGDATA->m_staticAlpha = static_data; } @@ -1904,8 +1915,11 @@ bool wxImage::ConvertAlphaToMask(unsigned char threshold) } } - free(M_IMGDATA->m_alpha); + if( !M_IMGDATA->m_staticAlpha ) + free(M_IMGDATA->m_alpha); + M_IMGDATA->m_alpha = NULL; + M_IMGDATA->m_staticAlpha = false; return true; } @@ -2052,8 +2066,7 @@ bool wxImage::SaveFile( const wxString& filename ) const wxImageHandler * pHandler = FindHandler(ext, -1); if (pHandler) { - SaveFile(filename, pHandler->GetType()); - return true; + return SaveFile(filename, pHandler->GetType()); } wxLogError(_("Can't save image to file '%s': unknown extension."), filename.c_str()); @@ -2145,13 +2158,19 @@ int wxImage::GetImageCount( wxInputStream &stream, long type ) if ( type == wxBITMAP_TYPE_ANY ) { - wxList &list=GetHandlers(); + const wxList& list = GetHandlers(); - for (wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext()) + for ( wxList::compatibility_iterator node = list.GetFirst(); + node; + node = node->GetNext() ) { - handler=(wxImageHandler*)node->GetData(); + handler = (wxImageHandler*)node->GetData(); if ( handler->CanRead(stream) ) - return handler->GetImageCount(stream); + { + const int count = handler->GetImageCount(stream); + if ( count >= 0 ) + return count; + } } @@ -2188,17 +2207,22 @@ bool wxImage::LoadFile( wxInputStream& stream, long type, int index ) if ( type == wxBITMAP_TYPE_ANY ) { - wxList &list=GetHandlers(); - - for ( wxList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext() ) + const wxList& list = GetHandlers(); + 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); + handler = (wxImageHandler*)node->GetData(); + if ( handler->CanRead(stream) && + handler->LoadFile(this, stream, true/*verbose*/, index) ) + { + return true; + } } wxLogWarning( _("No handler found for image type.") ); + return false; } @@ -2237,7 +2261,7 @@ bool wxImage::LoadFile( wxInputStream& stream, const wxString& mimetype, int ind if (stream.IsSeekable() && !handler->CanRead(stream)) { - wxLogError(_("Image file is not of type %s."), (const wxChar*) mimetype); + wxLogError(_("Image file is not of type %s."), mimetype); return false; } else @@ -2339,7 +2363,7 @@ wxImageHandler *wxImage::FindHandler( const wxString& name ) node = node->GetNext(); } - return 0; + return NULL; } wxImageHandler *wxImage::FindHandler( const wxString& extension, long bitmapType ) @@ -2353,7 +2377,7 @@ wxImageHandler *wxImage::FindHandler( const wxString& extension, long bitmapType return handler; node = node->GetNext(); } - return 0; + return NULL; } wxImageHandler *wxImage::FindHandler( long bitmapType ) @@ -2365,7 +2389,7 @@ wxImageHandler *wxImage::FindHandler( long bitmapType ) if (handler->GetType() == bitmapType) return handler; node = node->GetNext(); } - return 0; + return NULL; } wxImageHandler *wxImage::FindHandlerMime( const wxString& mimetype ) @@ -2377,7 +2401,7 @@ wxImageHandler *wxImage::FindHandlerMime( const wxString& mimetype ) if (handler->GetMimeType().IsSameAs(mimetype, false)) return handler; node = node->GetNext(); } - return 0; + return NULL; } void wxImage::InitStandardHandlers() @@ -2651,6 +2675,42 @@ bool wxImageHandler::CallDoCanRead(wxInputStream& stream) #endif // wxUSE_STREAMS +/* static */ +wxImageResolution +wxImageHandler::GetResolutionFromOptions(const wxImage& image, int *x, int *y) +{ + wxCHECK_MSG( x && y, wxIMAGE_RESOLUTION_NONE, _T("NULL pointer") ); + + if ( image.HasOption(wxIMAGE_OPTION_RESOLUTIONX) && + image.HasOption(wxIMAGE_OPTION_RESOLUTIONY) ) + { + *x = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONX); + *y = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONY); + } + else if ( image.HasOption(wxIMAGE_OPTION_RESOLUTION) ) + { + *x = + *y = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTION); + } + else // no resolution options specified + { + *x = + *y = 0; + + return wxIMAGE_RESOLUTION_NONE; + } + + // get the resolution unit too + int resUnit = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONUNIT); + if ( !resUnit ) + { + // this is the default + resUnit = wxIMAGE_RESOLUTION_INCHES; + } + + return (wxImageResolution)resUnit; +} + // ---------------------------------------------------------------------------- // image histogram stuff // ---------------------------------------------------------------------------- @@ -3095,8 +3155,8 @@ class wxImageModule: public wxModule DECLARE_DYNAMIC_CLASS(wxImageModule) public: wxImageModule() {} - bool OnInit() { wxImage::InitStandardHandlers(); return true; }; - void OnExit() { wxImage::CleanUpHandlers(); }; + bool OnInit() { wxImage::InitStandardHandlers(); return true; } + void OnExit() { wxImage::CleanUpHandlers(); } }; IMPLEMENT_DYNAMIC_CLASS(wxImageModule, wxModule)