+ 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 );
+ }
+
+ 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 / height) * old_width;
+
+ for (long i = 0; i < width; i++)
+ {
+ memcpy( target_data,
+ source_data + 3*(y_offset + ((i * old_width )/ width)),
+ 3 );
+ target_data += 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;
+}
+
+wxImage wxImage::Rotate90( bool clockwise ) const
+{
+ wxImage image;
+
+ wxCHECK_MSG( Ok(), image, wxT("invalid image") );
+
+ image.Create( M_IMGDATA->m_height, M_IMGDATA->m_width );
+
+ char unsigned *data = image.GetData();
+
+ 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 height = M_IMGDATA->m_height;
+ long width = M_IMGDATA->m_width;
+
+ char unsigned *source_data = M_IMGDATA->m_data;
+ char unsigned *target_data;
+
+ for (long j = 0; j < height; j++)
+ {
+ for (long i = 0; i < width; i++)
+ {
+ if (clockwise)
+ target_data = data + (((i+1)*height) - j - 1)*3;
+ else
+ target_data = data + ((height*(width-1)) + j - (i*height))*3;
+ memcpy( target_data, source_data, 3 );
+ source_data += 3;
+ }
+ }
+
+ return image;
+}
+
+wxImage wxImage::Mirror( bool horizontally ) const
+{
+ wxImage image;
+
+ wxCHECK_MSG( Ok(), image, wxT("invalid image") );
+
+ image.Create( M_IMGDATA->m_width, M_IMGDATA->m_height );
+
+ char unsigned *data = image.GetData();
+
+ 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 height = M_IMGDATA->m_height;
+ long width = M_IMGDATA->m_width;
+
+ char unsigned *source_data = M_IMGDATA->m_data;
+ char unsigned *target_data;
+
+ if (horizontally)
+ {
+ for (long j = 0; j < height; j++)
+ {
+ data += width*3;
+ target_data = data-3;
+ for (long i = 0; i < width; i++)
+ {
+ memcpy( target_data, source_data, 3 );
+ source_data += 3;
+ target_data -= 3;
+ }
+ }
+ }
+ else
+ {
+ for (long i = 0; i < height; i++)
+ {
+ target_data = data + 3*width*(height-1-i);
+ memcpy( target_data, source_data, (size_t)3*width );
+ source_data += 3*width;
+ }
+ }
+
+ return image;
+}
+
+wxImage wxImage::GetSubImage( const wxRect &rect ) const
+{
+ wxImage image;
+
+ wxCHECK_MSG( Ok(), image, wxT("invalid image") );
+
+ wxCHECK_MSG( (rect.GetLeft()>=0) && (rect.GetTop()>=0) && (rect.GetRight()<=GetWidth()) && (rect.GetBottom()<=GetHeight()),
+ image, wxT("invalid subimage size") );
+
+ int subwidth=rect.GetWidth();
+ const int subheight=rect.GetHeight();
+
+ image.Create( subwidth, subheight );
+
+ char unsigned *subdata = image.GetData(), *data=GetData();
+
+ wxCHECK_MSG( subdata, image, wxT("unable to create image") );