I'm working on a 2D Graphics Engine, when I use the following code to rotate the images I get 'write access violation' exception for newBits if the image dimensions have even numbers. There is no problem on odd numbered dimensions.
Here is my image rotation code :
bool Graphics::Raster::rotate(float angle)
{
try {
unsigned int xOrigin{ mWidth / 2 };
unsigned int yOrigin{ mHeight / 2 };
std::array<Math::Vector2D, 4> boundingBoxVertices;
Math::Matrix2x2 rotationMatrix;
boundingBoxVertices[0].setX((float)xOrigin * -1.0f);
boundingBoxVertices[0].setY((float)yOrigin);
boundingBoxVertices[1].setX((float)(mWidth - xOrigin) * 1.0f);
boundingBoxVertices[1].setY((float)yOrigin);
boundingBoxVertices[2].setX((float)(mWidth - xOrigin) * 1.0f);
boundingBoxVertices[2].setY((float)(mHeight - yOrigin) * -1.0f);
boundingBoxVertices[3].setX((float)xOrigin * -1.0f);
boundingBoxVertices[3].setY((float)(mHeight - yOrigin) * -1.0f);
int x{ 0 }, y{ 0 }, maxX{ 0 }, minX{ 0 }, maxY{ 0 }, minY{ 0 };
rotationMatrix.setToRotation(angle);
for (size_t i = 0; i < 4; ++i) {
boundingBoxVertices[i] *= rotationMatrix;
boundingBoxVertices[i].round();
x = (int)boundingBoxVertices[i].getX();
y = (int)boundingBoxVertices[i].getY();
if (x < minX) {
minX = x;
}
if (x > maxX) {
maxX = x;
}
if (y < minY) {
minY = y;
}
if (y > maxY) {
maxY = y;
}
}
size_t newWidth = (size_t)(maxX - minX);
size_t newHeight = (size_t)(maxY - minY);
BYTE* newBits{ nullptr };
if (newBits = new BYTE[newWidth * newHeight * 4]{ 0 }) {
int newOrgX = newWidth / 2;
int newOrgY = newHeight / 2;
Math::Vector2D pixVec{ 0.0f, 0.0f };
int oldCoordX{ 0 };
int oldCoordY{ 0 };
int newCoordX{ 0 };
int newCoordY{ 0 };
unsigned int oldIndex{ 0 };
unsigned int newIndex{ 0 };
for (size_t i = 0; i < mWidth * mHeight; ++i) {
oldCoordX = i % mWidth - xOrigin;
oldCoordY = yOrigin - i / mWidth;
pixVec.setX((float)oldCoordX);
pixVec.setY((float)oldCoordY);
pixVec *= rotationMatrix;
pixVec.round();
newCoordX = (unsigned int)(pixVec.getX() + newOrgX);
newCoordY = (unsigned int)(newOrgY - pixVec.getY());
oldIndex = i * 4;
newIndex = (newCoordY * newWidth * 4) + ((newCoordX) * 4);
newBits[newIndex + 0] = m32Bits[oldIndex + 0];
newBits[newIndex + 1] = m32Bits[oldIndex + 1];
newBits[newIndex + 2] = m32Bits[oldIndex + 2];
newBits[newIndex + 3] = m32Bits[oldIndex + 3];
}
if (angle != 0.0f || angle != 90.0f || angle != 180.0f || angle != 270.0f || angle != 360.0f ||
angle != -0.0f || angle != -90.0f || angle != -180.0f || angle != -270.0f || angle != -360.0f ) {
for (size_t i = 0; i < newHeight; ++i) {
for (size_t j = 0; j < newWidth; ++j) {
if (j != 0 && j != newWidth - 1) {
if (newBits[(i * newWidth * 4) + (j * 4) + 0] == 0 &&
newBits[(i * newWidth * 4) + (j * 4) + 1] == 0 &&
newBits[(i * newWidth * 4) + (j * 4) + 2] == 0 &&
newBits[(i * newWidth * 4) + (j * 4) + 3] == 0) {
newBits[(i * newWidth * 4) + (j * 4) + 0] = (newBits[(i * newWidth * 4) + ((j - 1) * 4) + 0] +
newBits[(i * newWidth * 4) + ((j + 1) * 4) + 0]) / 2;
newBits[(i * newWidth * 4) + (j * 4) + 1] = (newBits[(i * newWidth * 4) + ((j - 1) * 4) + 1] +
newBits[(i * newWidth * 4) + ((j + 1) * 4) + 1]) / 2;
newBits[(i * newWidth * 4) + (j * 4) + 2] = (newBits[(i * newWidth * 4) + ((j - 1) * 4) + 2] +
newBits[(i * newWidth * 4) + ((j + 1) * 4) + 2]) / 2;
newBits[(i * newWidth * 4) + (j * 4) + 3] = (newBits[(i * newWidth * 4) + ((j - 1) * 4) + 3] +
newBits[(i * newWidth * 4) + ((j + 1) * 4) + 3]) / 2;
}
}
}
}
}
if (set32Bits(newBits, newWidth, newHeight)) {
delete[] newBits;
return true;
} else {
delete[] newBits;
return false;
}
} else {
throw Error::Exception(L"Resim çevirme işlemi için hafızada yer açılamadı", L"Resim Düzenleme Hatası");
}
} catch (Error::Exception& ex) {
Error::ShowError(ex.getErrorMessage(), ex.getErrorTitle());
return false;
}
}
What am I doing wrong here? I can't use a third-party to rotate the images, I must use this function. Thanks in advance.