From 29435411cbf4e747f86d2b4280a75cdf7c80c4b1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 16 Mar 2007 00:23:07 +0000 Subject: [PATCH] call GetWidth/Height() only once in Rotate() and not inside the loops (patch 1681544) [backport from HEAD] git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@44840 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/common/image.cpp | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/common/image.cpp b/src/common/image.cpp index 3aae548ccc..6cb0dd0ad2 100644 --- a/src/common/image.cpp +++ b/src/common/image.cpp @@ -2811,20 +2811,23 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i bool has_alpha = HasAlpha(); + const int w = GetWidth(), + h = GetHeight(); + // Create pointer-based array to accelerate access to wxImage's data - unsigned char ** data = new unsigned char * [GetHeight()]; + unsigned char ** data = new unsigned char * [h]; data[0] = GetData(); - for (i = 1; i < GetHeight(); i++) - data[i] = data[i - 1] + (3 * GetWidth()); + for (i = 1; i < h; i++) + data[i] = data[i - 1] + (3 * w); // Same for alpha channel unsigned char ** alpha = NULL; if (has_alpha) { - alpha = new unsigned char * [GetHeight()]; + alpha = new unsigned char * [h]; alpha[0] = GetAlpha(); - for (i = 1; i < GetHeight(); i++) - alpha[i] = alpha[i - 1] + GetWidth(); + for (i = 1; i < h; i++) + alpha[i] = alpha[i - 1] + w; } // precompute coefficients for rotation formula @@ -2839,9 +2842,9 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i const wxRealPoint p0(centre_of_rotation.x, centre_of_rotation.y); wxRealPoint p1 = wxRotatePoint (0, 0, cos_angle, sin_angle, p0); - wxRealPoint p2 = wxRotatePoint (0, GetHeight(), cos_angle, sin_angle, p0); - wxRealPoint p3 = wxRotatePoint (GetWidth(), 0, cos_angle, sin_angle, p0); - wxRealPoint p4 = wxRotatePoint (GetWidth(), GetHeight(), cos_angle, sin_angle, p0); + wxRealPoint p2 = wxRotatePoint (0, h, cos_angle, sin_angle, p0); + wxRealPoint p3 = wxRotatePoint (w, 0, cos_angle, sin_angle, p0); + wxRealPoint p4 = wxRotatePoint (w, h, cos_angle, sin_angle, p0); int x1a = (int) floor (wxMin (wxMin(p1.x, p2.x), wxMin(p3.x, p4.x))); int y1a = (int) floor (wxMin (wxMin(p1.y, p2.y), wxMin(p3.y, p4.y))); @@ -2888,27 +2891,29 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i // performing an inverse rotation (a rotation of -angle) and getting the // pixel at those coordinates + const int rH = rotated.GetHeight(); + const int rW = rotated.GetWidth(); + // GRG: I've taken the (interpolating) test out of the loops, so that // it is done only once, instead of repeating it for each pixel. - int x; if (interpolating) { - for (int y = 0; y < rotated.GetHeight(); y++) + for (int y = 0; y < rH; y++) { - for (x = 0; x < rotated.GetWidth(); x++) + for (int x = 0; x < rW; x++) { wxRealPoint src = wxRotatePoint (x + x1a, y + y1a, cos_angle, -sin_angle, p0); - if (-0.25 < src.x && src.x < GetWidth() - 0.75 && - -0.25 < src.y && src.y < GetHeight() - 0.75) + if (-0.25 < src.x && src.x < w - 0.75 && + -0.25 < src.y && src.y < h - 0.75) { // interpolate using the 4 enclosing grid-points. Those // points can be obtained using floor and ceiling of the // exact coordinates of the point int x1, y1, x2, y2; - if (0 < src.x && src.x < GetWidth() - 1) + if (0 < src.x && src.x < w - 1) { x1 = wxRound(floor(src.x)); x2 = wxRound(ceil(src.x)); @@ -2918,7 +2923,7 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i x1 = x2 = wxRound (src.x); } - if (0 < src.y && src.y < GetHeight() - 1) + if (0 < src.y && src.y < h - 1) { y1 = wxRound(floor(src.y)); y2 = wxRound(ceil(src.y)); @@ -3041,17 +3046,16 @@ wxImage wxImage::Rotate(double angle, const wxPoint & centre_of_rotation, bool i } else // not interpolating { - for (int y = 0; y < rotated.GetHeight(); y++) + for (int y = 0; y < rH; y++) { - for (x = 0; x < rotated.GetWidth(); x++) + for (int x = 0; x < rW; x++) { wxRealPoint src = wxRotatePoint (x + x1a, y + y1a, cos_angle, -sin_angle, p0); const int xs = wxRound (src.x); // wxRound rounds to the const int ys = wxRound (src.y); // closest integer - if (0 <= xs && xs < GetWidth() && - 0 <= ys && ys < GetHeight()) + if (0 <= xs && xs < w && 0 <= ys && ys < h) { unsigned char *p = data[ys] + (3 * xs); *(dst++) = *(p++);