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
This commit is contained in:
@@ -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++);
|
||||
|
Reference in New Issue
Block a user