X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3f74b7aeb69624c0b0aabb1ab01d241a80063ebd..8261989803268d7cfa3e83634686d3abfdd0c3b3:/src/common/image.cpp diff --git a/src/common/image.cpp b/src/common/image.cpp index f17d1cbf25..6b431715c3 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -1089,35 +1089,60 @@ wxImage wxImage::Rotate90( bool clockwise ) const } unsigned char *data = image.GetData(); - const unsigned char *source_data = M_IMGDATA->m_data; unsigned char *target_data; - unsigned char *alpha_data = image.GetAlpha(); - const unsigned char *source_alpha = M_IMGDATA->m_alpha; - unsigned char *target_alpha = 0 ; - for (long j = 0; j < height; j++) + // we rotate the image in 21-pixel (63-byte) wide strips + // to make better use of cpu cache - memory transfers + // (note: while much better than single-pixel "strips", + // our vertical strips will still generally straddle cachelines) + for (long ii = 0; ii < width; ) { - for (long i = 0; i < width; i++) + long next_ii = wxMin(ii + 21, width); + + for (long j = 0; j < height; j++) { - if (clockwise) + const unsigned char *source_data + = M_IMGDATA->m_data + (j*width + ii)*3; + + for (long i = ii; i < next_ii; i++) { - target_data = data + (((i+1)*height) - j - 1)*3; - if (source_alpha) - target_alpha = alpha_data + (((i+1)*height) - j - 1); + if ( clockwise ) + { + target_data = data + (((i+1)*height) - j - 1)*3; + } + else + { + target_data = data + ((height*(width - 1 - i)) + j)*3; + } + memcpy( target_data, source_data, 3 ); + source_data += 3; } - else + } + + ii = next_ii; + } + + const unsigned char *source_alpha = M_IMGDATA->m_alpha; + + if ( source_alpha ) + { + unsigned char *alpha_data = image.GetAlpha(); + unsigned char *target_alpha = 0 ; + + for (long j = 0; j < height; j++) + { + for (long i = 0; i < width; i++) { - target_data = data + ((height*(width-1)) + j - (i*height))*3; - if (source_alpha) + if ( clockwise ) + { + target_alpha = alpha_data + (((i+1)*height) - j - 1); + } + else + { target_alpha = alpha_data + ((height*(width-1)) + j - (i*height)); - } - memcpy( target_data, source_data, 3 ); - source_data += 3; + } - if (source_alpha) - { - memcpy( target_alpha, source_alpha, 1 ); - source_alpha += 1; + *target_alpha = *source_alpha++; } } } @@ -2376,8 +2401,20 @@ bool wxImage::DoLoad(wxImageHandler& handler, wxInputStream& stream, int index) const unsigned maxWidth = GetOptionInt(wxIMAGE_OPTION_MAX_WIDTH), maxHeight = GetOptionInt(wxIMAGE_OPTION_MAX_HEIGHT); + // Preserve the original stream position if possible to rewind back to it + // if we failed to load the file -- maybe the next handler that we try can + // succeed after us then. + wxFileOffset posOld = wxInvalidOffset; + if ( stream.IsSeekable() ) + posOld = stream.TellI(); + if ( !handler.LoadFile(this, stream, true/*verbose*/, index) ) + { + if ( posOld != wxInvalidOffset ) + stream.SeekI(posOld); + return false; + } // rescale the image to the specified size if needed if ( maxWidth || maxHeight )